From 87c5517bddaf369ac6f28cffc38cb08141014e4a Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Fri, 17 Feb 2023 11:42:44 +0100 Subject: [PATCH] Swap texture window only when the twin value changes. Further reduces texture window commands, especially when drawing non-tiling faces. Also cleans up the drawing code a bit. --- draw.h | 8 ++++++++ world.c | 27 +++++++++++++-------------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/draw.h b/draw.h index 4713b71..ca2a20c 100644 --- a/draw.h +++ b/draw.h @@ -51,6 +51,14 @@ static u_int color_white = ((255 << 16) | (255 << 8) | 255); +static INLINE void draw_texwindow(unsigned int texWindow, u_long *ot) +{ + DR_TWIN *twin = (DR_TWIN*)mem_prim(sizeof(DR_TWIN)); + setlen(twin, 1); + twin->code[0] = texWindow; + addPrim(ot, twin); +} + static INLINE void draw_triangle_lit(SVECTOR *verts, u_long *ot) { // Draw a single triangle diff --git a/world.c b/world.c index f64db10..cd7fb0f 100644 --- a/world.c +++ b/world.c @@ -199,6 +199,9 @@ static void (*world_drawface)(const world_t*, const ps1bsp_face_t*, u_long *ot) static void world_drawFaces(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; + // Draw the faces in front-to-back order. There are two advantages to this: // 1) We don't need to do any depth calculations. The ordering table will be rendered in reverse order, i.e. back-to-front. // 2) If we need to stop drawing because the primitive buffer is full, we'll only be culling distant faces. @@ -208,18 +211,20 @@ 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; - world_drawface(world, face, curOT); - // Texture window commands needs to be placed *after* the draw commands, because the commands are executed in reverse order - if (face->nextFace == NULL || face->textureId != face->nextFace->textureId) + // Set the texture window for the previous face if it changes in-between faces + const ps1bsp_texture_t *texture = &world->textures[face->textureId]; + if (prevTexWin != texture->twin) { - const ps1bsp_texture_t *texture = &world->textures[face->textureId]; - DR_TWIN *twin = (DR_TWIN*)mem_prim(sizeof(DR_TWIN)); - setlen(twin, 1); - twin->code[0] = texture->twin; - addPrim(curOT, twin); + draw_texwindow(prevTexWin, curOT); + prevTexWin = texture->twin; } + + world_drawface(world, face, curOT); } + + // Set the texture window for the first face to be drawn + draw_texwindow(prevTexWin, curOT); } // Simplified BSP subtree traversal specifically for sorting faces of brush models. @@ -492,11 +497,5 @@ void world_draw(const world_t *world) else world_drawface = &world_drawface_lit; - // Make sure we set the texture window back to default after drawing the world - DR_TWIN *twin = (DR_TWIN*)mem_prim(sizeof(DR_TWIN)); - setlen(twin, 1); - twin->code[0] = 0xe2000000; - addPrim(curOT, twin); - world_drawFaces(world, firstFace); }