Browse Source

Rewrote model rendering code using GTE acceleration. Now with 100% more perspective!

master
Nico de Poel 3 years ago
parent
commit
5e0641c9ff
  1. 101
      main.c

101
main.c

@ -31,7 +31,7 @@
#define SCREENHEIGHT 240
#define NUMVERTEXNORMALS 162
static int anorms[NUMVERTEXNORMALS][3] = {
static short anorms[NUMVERTEXNORMALS][3] = {
#include "ps1anorms.h"
};
@ -78,6 +78,21 @@ typedef struct
ps1mdl_t playerModel, shamblerModel;
ps1skin_t playerSkin, shamblerSkin;
SVECTOR rot = { 0 };
VECTOR pos = { -200, 128, 64 };
MATRIX color_mtx = {
ONE, 0, 0,
ONE, 0, 0,
ONE, 0, 0
};
MATRIX light_mtx = {
ONE, 0, 0,
0, 0, 0,
0, 0, 0
};
void loadModel(const u_long* data, ps1mdl_t *mdl)
{
const char *bytes = (const char*)data;
@ -168,6 +183,10 @@ void init(void)
loadModel(mdl_shambler, &shamblerModel);
loadSkin(tim_shambler_f, tim_shambler_b, &shamblerSkin);
InitGeom();
gte_SetGeomOffset(SCREENWIDTH >> 1, SCREENHEIGHT >> 1);
gte_SetGeomScreen(SCREENWIDTH >> 1); // Screen depth for FOV control
// Set texture page for the entire drawing environment. Nice in some cases perhaps, but not what we need.
//draw[0].tpage = getTPage(playerFrontTex.mode & 0x3, 0, playerFrontTex.prect->x, playerFrontTex.prect->y);
//draw[1].tpage = getTPage(playerFrontTex.mode & 0x3, 0, playerFrontTex.prect->x, playerFrontTex.prect->y);
@ -326,10 +345,13 @@ static int fakeLight(const int *norm)
return lit;
}
SVECTOR outPos;
void drawModel(ps1mdl_t *model, ps1skin_t *skin, int xOffset, int frameCounter)
{
ps1texture_t *tex;
short u0, u1, u2, uoffs, voffs;
int p;
int frameNum = frameCounter % model->header->frameCount;
int vertOffs = frameNum * model->header->vertexCount;
@ -343,20 +365,31 @@ void drawModel(ps1mdl_t *model, ps1skin_t *skin, int xOffset, int frameCounter)
ps1mdl_vertex_t *v1 = &model->vertices[tri->vertexIndex[1] + vertOffs];
ps1mdl_vertex_t *v2 = &model->vertices[tri->vertexIndex[2] + vertOffs];
// Normally you'd have GTE do this but we're just going for a quick hack now
unsigned short depth = ((unsigned short)v0->position[1] + (unsigned short)v1->position[1] + (unsigned short)v2->position[1]) / 3;
if (depth >= OTLEN)
// Swizzle the coordinates because Quake Z is up
SVECTOR pos0 = { v0->position[0], -v0->position[2], v0->position[1] };
SVECTOR pos1 = { v1->position[0], -v1->position[2], v1->position[1] };
SVECTOR pos2 = { v2->position[0], -v2->position[2], v2->position[1] };
gte_ldv3(&pos0, &pos1, &pos2);
gte_rtpt(); // Rotation, Translation and Perspective triplet (all three vertices at once)
// Normal clipping for backface culling
gte_nclip();
gte_stopz(&p);
if (p < 0)
continue;
// Average Z for depth sorting
gte_avsz3();
gte_stotz(&p);
unsigned short depth = p;//p >> 2;
if (depth < 0 || depth >= OTLEN)
continue;
ps1mdl_texcoord_t *tc0 = &model->texCoords[tri->vertexIndex[0]];
ps1mdl_texcoord_t *tc1 = &model->texCoords[tri->vertexIndex[1]];
ps1mdl_texcoord_t *tc2 = &model->texCoords[tri->vertexIndex[2]];
// Calculate some Lambert shading based on a static light vector
int lit0 = fakeLight(anorms[v0->normalIndex]);
int lit1 = fakeLight(anorms[v1->normalIndex]);
int lit2 = fakeLight(anorms[v2->normalIndex]);
if (tri->frontFace)
{
u0 = tc0->u, u1 = tc1->u, u2 = tc2->u;
@ -375,11 +408,25 @@ void drawModel(ps1mdl_t *model, ps1skin_t *skin, int xOffset, int frameCounter)
POLY_GT3 *poly = (POLY_GT3*)nextpri;
setPolyGT3(poly);
setXY3(poly, xOffset + v0->position[0], 240 - v0->position[2], xOffset + v1->position[0], 240 - v1->position[2], xOffset + v2->position[0], 240 - v2->position[2]);
// Store transformed vertex coordinates in screen space
gte_stsxy0(&poly->x0);
gte_stsxy1(&poly->x1);
gte_stsxy2(&poly->x2);
// Copy some values for on-screen debugging
outPos.vx = poly->x0;
outPos.vy = poly->y0;
outPos.vz = p;
// Calculate vertex color based on normal
gte_ldrgb(&poly->r0);
gte_ldv3(anorms[v0->normalIndex], anorms[v1->normalIndex], anorms[v2->normalIndex]);
gte_nct();
gte_strgb3(&poly->r0, &poly->r1, &poly->r2);
// Set texture parameters
setUV3(poly, uoffs + u0, voffs + tc0->v, uoffs + u1, voffs + tc1->v, uoffs + u2, voffs + tc2->v);
setRGB0(poly, lit0, lit0, lit0);
setRGB1(poly, lit1, lit1, lit1);
setRGB2(poly, lit2, lit2, lit2);
setClut(poly, tex->crect.x, tex->crect.y);
setTPage(poly, tex->mode & 0x3, 0, tex->prect.x, tex->prect.y);
@ -392,30 +439,28 @@ void drawStuff(int counter)
{
ClearOTagR(ot[db], OTLEN);
// Print the obligatory hello world and counter to show that the
// program isn't locking up to the last created text stream
FntPrint(-1, "COUNTER=%d, SIN=%d\n", counter, isin(counter));
FntPrint(-1, "Image x %d y %d w %d h %d mode 0x%x\n", playerSkin.front.prect.x, playerSkin.front.prect.y, playerSkin.front.prect.w, playerSkin.front.prect.h, playerSkin.front.mode);
FntPrint(-1, "Model: %d tris, %d verts\n", playerModel.header->triangleCount, playerModel.header->vertexCount);
FntPrint(-1, "Trsf: (%d, %d, %d)\n", outPos.vx, outPos.vy, outPos.vz);
// Draw the last created text stream
FntFlush(-1);
drawModel(&playerModel, &playerSkin, -40, counter >> 2);
drawModel(&shamblerModel, &shamblerSkin, 80, counter >> 2);
gte_SetBackColor(48, 48, 48); // Ambient light color
gte_SetColorMatrix(&color_mtx); // Light color and direction
// int r, g, b;
// lerpcol(255, 255, 0, 255, 0, 0, (icos(counter * 32) + 4096) >> 1, &r, &g, &b);
// addTile(32, 32, 64, 64, r, g, b);
MATRIX mtx, lmtx;
RotMatrix(&rot, &mtx);
TransMatrix(&mtx, &pos);
// lerpcol(0, 255, 255, 0, 255, 0, (icos(counter * 24 + 512) + 4096) >> 1, &r, &g, &b);
// addTile(128, 160, 48, 48, r, g, b);
MulMatrix0(&light_mtx, &mtx, &lmtx);
// addColoredTriangle(260, 140, 220, 220, 300, 220, 0xFF0000, 0x00FF00, 0x0000FF, 0);
// addTexturedTriangle(260, 40, 220, 120, 300, 120, 0, 94, 74, 124, 58, 1, &playerSkin.front);
// addTexturedSprite(20, 140, 80, 80, &playerSkin.front);
// addTexturedSprite(80, 40, 154, 114, &shamblerSkin.front);
gte_SetRotMatrix(&mtx);
gte_SetTransMatrix(&mtx);
gte_SetLightMatrix(&lmtx);
drawModel(&playerModel, &playerSkin, -40, counter >> 2);
//drawModel(&shamblerModel, &shamblerSkin, 80, counter >> 2);
}
// Main function, program entrypoint

Loading…
Cancel
Save