|
|
@ -83,9 +83,34 @@ static INLINE char world_cull_backface(const world_t *world, const ps1bsp_face_t |
|
|
return ((*dot >= 0) ^ face->side); |
|
|
return ((*dot >= 0) ^ face->side); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void world_drawface_fast(const world_t *world, const ps1bsp_face_t *face) |
|
|
|
|
|
{ |
|
|
|
|
|
// TODO: early primitive buffer check (POLY_G4) |
|
|
|
|
|
|
|
|
|
|
|
short dot; |
|
|
|
|
|
if (world_cull_backface(world, face, &dot)) |
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
// Draw untextured, vertex colored faces, skipping the entire polygon tessellation step |
|
|
|
|
|
SVECTOR *verts = (SVECTOR*)(scratchpad + 256); |
|
|
|
|
|
SVECTOR *curVert = verts; |
|
|
|
|
|
const ps1bsp_facevertex_t *faceVertex = &world->faceVertices[face->firstFaceVertex]; |
|
|
|
|
|
for (u_char vertIdx = 0; vertIdx < face->numFaceVertices; ++vertIdx, ++faceVertex, ++curVert) |
|
|
|
|
|
{ |
|
|
|
|
|
const ps1bsp_vertex_t *vert = &world->vertices[faceVertex->index]; |
|
|
|
|
|
*curVert = *((SVECTOR*)vert); |
|
|
|
|
|
curVert->pad = (unsigned short)(size_t)face & 0xFF; // TODO: apply averaged light * color value |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (face->numFaceVertices == 3) |
|
|
|
|
|
draw_trianglefan_lit(verts, 3); |
|
|
|
|
|
else |
|
|
|
|
|
draw_quadstrip_lit(verts, face->numFaceVertices); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
static void world_drawface_lit(const world_t *world, const ps1bsp_face_t *face) |
|
|
static void world_drawface_lit(const world_t *world, const ps1bsp_face_t *face) |
|
|
{ |
|
|
{ |
|
|
// TODO: early primitive buffer check |
|
|
|
|
|
|
|
|
// TODO: early primitive buffer check (POLY_G4) |
|
|
|
|
|
|
|
|
short dot; |
|
|
short dot; |
|
|
if (world_cull_backface(world, face, &dot)) |
|
|
if (world_cull_backface(world, face, &dot)) |
|
|
@ -120,7 +145,7 @@ static void world_drawface_textured(const world_t *world, const ps1bsp_face_t *f |
|
|
if (world_cull_backface(world, face, &dot)) |
|
|
if (world_cull_backface(world, face, &dot)) |
|
|
return; |
|
|
return; |
|
|
|
|
|
|
|
|
// TODO: do an early primitive buffer check here, so we can skip vertex copying if it's already full |
|
|
|
|
|
|
|
|
// TODO: do an early primitive buffer check here (POLY_GT4), so we can skip vertex copying if it's already full |
|
|
// When doing tessellation, we need the above dot product to decide how many polys to draw, so we can only safely check the primbuffer size here |
|
|
// When doing tessellation, we need the above dot product to decide how many polys to draw, so we can only safely check the primbuffer size here |
|
|
// Though since we're drawing front-to-back and tessellation will only happen close to the camera, I suppose we could get away with just checking for non-tessellated polycounts |
|
|
// Though since we're drawing front-to-back and tessellation will only happen close to the camera, I suppose we could get away with just checking for non-tessellated polycounts |
|
|
|
|
|
|
|
|
@ -148,7 +173,7 @@ static void world_drawface_textured(const world_t *world, const ps1bsp_face_t *f |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static void (*world_drawface)(const world_t*, const ps1bsp_face_t*) = &world_drawface_textured; |
|
|
|
|
|
|
|
|
static void (*world_drawface)(const world_t*, const ps1bsp_face_t*) = &world_drawface_fast; |
|
|
|
|
|
|
|
|
static void world_drawnode(const world_t *world, short nodeIdx, u_char *pvs) |
|
|
static void world_drawnode(const world_t *world, short nodeIdx, u_char *pvs) |
|
|
{ |
|
|
{ |
|
|
|