|
|
@ -76,8 +76,8 @@ typedef struct |
|
|
ps1texture_t front, back; |
|
|
ps1texture_t front, back; |
|
|
} ps1skin_t; |
|
|
} ps1skin_t; |
|
|
|
|
|
|
|
|
ps1mdl_t playerModel = { .position = { -200, 160, 400 }, .rotation = { 0 } }; |
|
|
|
|
|
ps1mdl_t shamblerModel = { .position = { 200, 160, 400 }, .rotation = { 0 } }; |
|
|
|
|
|
|
|
|
ps1mdl_t playerModel = { .position = { -200, 200, -160 }, .rotation = { 0 } }; |
|
|
|
|
|
ps1mdl_t shamblerModel = { .position = { 100, 200, -160 }, .rotation = { 0 } }; |
|
|
ps1skin_t playerSkin, shamblerSkin; |
|
|
ps1skin_t playerSkin, shamblerSkin; |
|
|
|
|
|
|
|
|
const MATRIX identity = { |
|
|
const MATRIX identity = { |
|
|
@ -87,6 +87,13 @@ const MATRIX identity = { |
|
|
0, 0, 0, |
|
|
0, 0, 0, |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const MATRIX quake_swizzle = { |
|
|
|
|
|
ONE, 0, 0, |
|
|
|
|
|
0, 0, -ONE, |
|
|
|
|
|
0, ONE, 0, |
|
|
|
|
|
0, 0, 0, |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
MATRIX light_cols = { |
|
|
MATRIX light_cols = { |
|
|
ONE, 0, 0, |
|
|
ONE, 0, 0, |
|
|
ONE, 0, 0, |
|
|
ONE, 0, 0, |
|
|
@ -361,7 +368,7 @@ static int fakeLight(const int *norm) |
|
|
|
|
|
|
|
|
SVECTOR outPos; |
|
|
SVECTOR outPos; |
|
|
|
|
|
|
|
|
void drawModel(ps1mdl_t *model, ps1skin_t *skin, int frameCounter) |
|
|
|
|
|
|
|
|
void drawModel(MATRIX *view_matrix, ps1mdl_t *model, ps1skin_t *skin, int frameCounter) |
|
|
{ |
|
|
{ |
|
|
ps1texture_t *tex; |
|
|
ps1texture_t *tex; |
|
|
short u0, u1, u2, uoffs, voffs; |
|
|
short u0, u1, u2, uoffs, voffs; |
|
|
@ -375,52 +382,18 @@ void drawModel(ps1mdl_t *model, ps1skin_t *skin, int frameCounter) |
|
|
int *scale = model->header->scale; |
|
|
int *scale = model->header->scale; |
|
|
int *translate = model->header->translate; |
|
|
int *translate = model->header->translate; |
|
|
|
|
|
|
|
|
// Expected order of things: |
|
|
|
|
|
// - Initial scale matrix to correct aspect ratio |
|
|
|
|
|
// - Coordinate system swizzle (scale) (can probably be combined with the above) |
|
|
|
|
|
// - Camera inverse translation |
|
|
|
|
|
// - Camera inverse rotation (apply on top of camera translation) |
|
|
|
|
|
// - Multiply light matrix (lights will be in Quake coordinate system) |
|
|
|
|
|
// - Push matrix |
|
|
|
|
|
// - Entity local rotation |
|
|
|
|
|
// - Entity local translation |
|
|
|
|
|
// - Model internal scale |
|
|
|
|
|
// - Model internal translate |
|
|
|
|
|
// - Render |
|
|
|
|
|
// - Pop matrix |
|
|
|
|
|
|
|
|
|
|
|
// TODO: this can all probably be done much more efficiently with the CompMatrixLV function. Doing it manually first though to better understand it. |
|
|
|
|
|
MATRIX cam_mtx = identity; |
|
|
|
|
|
//VECTOR cam_inv_pos = { -cam_pos.vx, -cam_pos.vy, -cam_pos.vz }; |
|
|
|
|
|
ScaleMatrixL(&cam_mtx, &aspect_scale); // Aspect ratio correction |
|
|
|
|
|
//TransMatrix(&cam_mtx, &cam_inv_pos); |
|
|
|
|
|
//MATRIX cam_rot_mtx; |
|
|
|
|
|
//SVECTOR cam_inv_rot = { -cam_rot.vx, -cam_rot.vy, -cam_rot.vz, 0 }; |
|
|
|
|
|
//RotMatrix(&cam_inv_rot, &cam_rot_mtx); |
|
|
|
|
|
//MulMatrix(&cam_mtx, &cam_rot_mtx); |
|
|
|
|
|
|
|
|
|
|
|
MATRIX light_mtx; |
|
|
|
|
|
// MulMatrix0(&light_dirs, &cam_mtx, &light_mtx); |
|
|
|
|
|
// gte_SetLightMatrix(&light_mtx); |
|
|
|
|
|
|
|
|
|
|
|
MATRIX model_mtx; |
|
|
MATRIX model_mtx; |
|
|
RotMatrix(&model->rotation, &model_mtx); |
|
|
RotMatrix(&model->rotation, &model_mtx); |
|
|
TransMatrix(&model_mtx, &model->position); |
|
|
TransMatrix(&model_mtx, &model->position); |
|
|
|
|
|
|
|
|
MulMatrix(&model_mtx, &cam_mtx); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MATRIX light_mtx; |
|
|
MulMatrix0(&light_dirs, &model_mtx, &light_mtx); |
|
|
MulMatrix0(&light_dirs, &model_mtx, &light_mtx); |
|
|
gte_SetLightMatrix(&light_mtx); |
|
|
gte_SetLightMatrix(&light_mtx); |
|
|
|
|
|
|
|
|
// Model internal scale and translate, to transform vertices from [0..255] range to a larger dynamic range with appropriate world-relative size |
|
|
|
|
|
// Swizzle the coordinates because Quake Z is up |
|
|
|
|
|
// Finding the appropriate scale range here is tricky. Without the << 2 scale the vertex coordinates become so small that you lose depth precision. |
|
|
|
|
|
MATRIX local_mtx = { .m = { ONE << 2, 0, 0, 0, 0, -ONE << 2, 0, ONE << 2, 0 }, .t = { 0 } }; |
|
|
|
|
|
ScaleMatrixL(&local_mtx, (VECTOR*)scale); |
|
|
|
|
|
TransMatrix(&local_mtx, (VECTOR*)translate); |
|
|
|
|
|
MulMatrix(&model_mtx, &local_mtx); |
|
|
|
|
|
|
|
|
CompMatrixLV(view_matrix, &model_mtx, &model_mtx); |
|
|
|
|
|
|
|
|
|
|
|
PushMatrix(); |
|
|
|
|
|
|
|
|
// TODO: set these after setting up camera, then use PushMatrix + CompMatrixLV for entities? |
|
|
|
|
|
gte_SetRotMatrix(&model_mtx); |
|
|
gte_SetRotMatrix(&model_mtx); |
|
|
gte_SetTransMatrix(&model_mtx); |
|
|
gte_SetTransMatrix(&model_mtx); |
|
|
|
|
|
|
|
|
@ -499,6 +472,8 @@ void drawModel(ps1mdl_t *model, ps1skin_t *skin, int frameCounter) |
|
|
addPrim(ot[db] + depth, poly); |
|
|
addPrim(ot[db] + depth, poly); |
|
|
nextpri += sizeof(POLY_GT3); |
|
|
nextpri += sizeof(POLY_GT3); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
PopMatrix(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void drawStuff(int counter) |
|
|
void drawStuff(int counter) |
|
|
@ -515,8 +490,38 @@ void drawStuff(int counter) |
|
|
gte_SetBackColor(48, 48, 48); // Ambient light color |
|
|
gte_SetBackColor(48, 48, 48); // Ambient light color |
|
|
gte_SetColorMatrix(&light_cols); // Light color (up to three different lights) |
|
|
gte_SetColorMatrix(&light_cols); // Light color (up to three different lights) |
|
|
|
|
|
|
|
|
drawModel(&playerModel, &playerSkin, counter >> 2); |
|
|
|
|
|
drawModel(&shamblerModel, &shamblerSkin, counter >> 2); |
|
|
|
|
|
|
|
|
// Expected order of things: |
|
|
|
|
|
// - Initial scale matrix to correct aspect ratio |
|
|
|
|
|
// - Coordinate system swizzle (scale) (can probably be combined with the above) |
|
|
|
|
|
// - Camera inverse translation |
|
|
|
|
|
// - Camera inverse rotation (apply on top of camera translation) |
|
|
|
|
|
// - Multiply light matrix (lights will be in Quake coordinate system) |
|
|
|
|
|
// - Push matrix |
|
|
|
|
|
// - Entity local rotation |
|
|
|
|
|
// - Entity local translation |
|
|
|
|
|
// - Model internal scale |
|
|
|
|
|
// - Model internal translate |
|
|
|
|
|
// - Render |
|
|
|
|
|
// - Pop matrix |
|
|
|
|
|
|
|
|
|
|
|
MATRIX proj_matrix = quake_swizzle; // Swizzle coordinates so that everything is in Quake coordinate system (Z up) |
|
|
|
|
|
ScaleMatrixL(&proj_matrix, &aspect_scale); // Apply aspect ratio correction for the current resolution |
|
|
|
|
|
|
|
|
|
|
|
MATRIX view_matrix; |
|
|
|
|
|
SVECTOR trot = { 0, 0, 0, 0 }; // TODO: camera rotation (in Quake coordinates) |
|
|
|
|
|
VECTOR tpos = { 0, 0, 0 }; // TODO: camera position (in Quake coordinates) |
|
|
|
|
|
RotMatrix(&trot, &view_matrix); // Set camera rotation part of the view matrix |
|
|
|
|
|
ApplyMatrixLV(&view_matrix, &tpos, &tpos); // Apply camera rotation to camera position |
|
|
|
|
|
TransMatrix(&view_matrix, &tpos); // Apply transformed position to the translation part of the view matrix |
|
|
|
|
|
|
|
|
|
|
|
// Compose view and projection matrices to obtain a combined view-projection matrix |
|
|
|
|
|
CompMatrixLV(&proj_matrix, &view_matrix, &view_matrix); |
|
|
|
|
|
|
|
|
|
|
|
gte_SetRotMatrix(&view_matrix); |
|
|
|
|
|
gte_SetTransMatrix(&view_matrix); |
|
|
|
|
|
|
|
|
|
|
|
drawModel(&view_matrix, &playerModel, &playerSkin, counter >> 2); |
|
|
|
|
|
drawModel(&view_matrix, &shamblerModel, &shamblerSkin, counter >> 2); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Main function, program entrypoint |
|
|
// Main function, program entrypoint |
|
|
@ -531,8 +536,6 @@ int main(int argc, const char *argv[]) |
|
|
counter = 0; |
|
|
counter = 0; |
|
|
while(1) |
|
|
while(1) |
|
|
{ |
|
|
{ |
|
|
playerModel.rotation.vz = (counter << 2) % ONE; |
|
|
|
|
|
|
|
|
|
|
|
drawStuff(counter); |
|
|
drawStuff(counter); |
|
|
|
|
|
|
|
|
// Update display |
|
|
// Update display |
|
|
|