diff --git a/ps1bsp.h b/ps1bsp.h index bf2ca32..9570fda 100755 --- a/ps1bsp.h +++ b/ps1bsp.h @@ -53,7 +53,7 @@ typedef struct typedef struct { short x, y, z; - short pad; // TODO: Turn into color * light averaged over all adjacent faces, for untextured gouraud shaded drawing at range + short pad; } ps1bsp_vertex_t; // Texture UV and lighting data for a vertex on a particular polygon. @@ -73,7 +73,6 @@ typedef struct unsigned short numPolyVertices; } ps1bsp_polygon_t; -// TODO: should become obsolete; let faces directly reference ps1bsp_vertex_t typedef struct { unsigned short index; diff --git a/test.ps1bsp b/test.ps1bsp index 585561d..0ff67a1 100755 Binary files a/test.ps1bsp and b/test.ps1bsp differ diff --git a/world.c b/world.c index 31c0f20..ded0618 100644 --- a/world.c +++ b/world.c @@ -83,9 +83,34 @@ static INLINE char world_cull_backface(const world_t *world, const ps1bsp_face_t 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) { - // TODO: early primitive buffer check + // TODO: early primitive buffer check (POLY_G4) short 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)) 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 // 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) {