Browse Source

Added a fast face drawing routine, which is basically what we had before:

- Faces directly point to vertices using the face vertex buffer
- Draw faces as quad strips from the original face data, without tessellation
unrollquadloop
Nico de Poel 3 years ago
parent
commit
7232e061d7
  1. 3
      ps1bsp.h
  2. BIN
      test.ps1bsp
  3. 31
      world.c

3
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;

BIN
test.ps1bsp

31
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)
{

Loading…
Cancel
Save