From 0ea3df5de9583b4201a0c3e664701824f90dc32b Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Fri, 17 Feb 2023 11:54:52 +0100 Subject: [PATCH] Selection between textured/untextured face drawing functions moved one abstraction level higher. This eliminates redundant texture window swaps when drawing untextured, and is a bit faster overall as well. --- world.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/world.c b/world.c index cd7fb0f..013ed1b 100644 --- a/world.c +++ b/world.c @@ -195,9 +195,19 @@ 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*, u_long *ot) = &world_drawface_fast; +static void world_drawFacesLit(const world_t *world, const ps1bsp_face_t *firstFace) +{ + for (const ps1bsp_face_t *face = firstFace; face != NULL; face = face->nextFace) + { + // Early primitive buffer check + if (!mem_checkprim(sizeof(POLY_G4), face->totalPrimitives)) + break; -static void world_drawFaces(const world_t *world, const ps1bsp_face_t *firstFace) + world_drawface_lit(world, face, curOT); + } +} + +static void world_drawFacesTextured(const world_t *world, const ps1bsp_face_t *firstFace) { // Make sure we set the texture window back to default after drawing the world unsigned int prevTexWin = 0xe2000000; @@ -211,8 +221,8 @@ static void world_drawFaces(const world_t *world, const ps1bsp_face_t *firstFace if (!mem_checkprim(sizeof(POLY_GT4) + sizeof(DR_TWIN), face->totalPrimitives)) break; - // Texture window commands needs to be placed *after* the draw commands, because the commands are executed in reverse order // Set the texture window for the previous face if it changes in-between faces + // Texture window commands needs to be placed *after* the draw commands, because the commands are executed in reverse order const ps1bsp_texture_t *texture = &world->textures[face->textureId]; if (prevTexWin != texture->twin) { @@ -220,13 +230,15 @@ static void world_drawFaces(const world_t *world, const ps1bsp_face_t *firstFace prevTexWin = texture->twin; } - world_drawface(world, face, curOT); + world_drawface_textured(world, face, curOT); } // Set the texture window for the first face to be drawn draw_texwindow(prevTexWin, curOT); } +static void (*world_drawFaces)(const world_t *world, const ps1bsp_face_t *firstFace) = &world_drawFacesTextured; + // Simplified BSP subtree traversal specifically for sorting faces of brush models. // This skips the frustum culling and PVS culling stages, as this will have already been done on the leafs containing the model. static ps1bsp_face_t *world_sortModelFaces(const world_t* world, const ps1bsp_model_t* model, u_long frameNum, ps1bsp_face_t **lastFace) @@ -493,9 +505,9 @@ void world_draw(const world_t *world) ps1bsp_face_t *firstFace = world_sortFaces(world, firstLeaf); if (enableTexturing) - world_drawface = &world_drawface_textured; + world_drawFaces = &world_drawFacesTextured; else - world_drawface = &world_drawface_lit; + world_drawFaces = &world_drawFacesLit; world_drawFaces(world, firstFace); }