From caef58820a8e3982e49389c1ee74cb22d58cd859 Mon Sep 17 00:00:00 2001 From: myT <> Date: Sun, 15 Dec 2024 20:47:10 +0100 Subject: [PATCH] fixed unlit maps forcing shader duplication - assigning a new lightmapIndex value makes shader search fail - fog shader duplicates don't have isFog set --- code/renderer/tr_bsp.cpp | 24 +++++++++++++++++------- code/renderer/tr_local.h | 2 +- code/renderer/tr_shader.cpp | 15 ++++++++------- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/code/renderer/tr_bsp.cpp b/code/renderer/tr_bsp.cpp index adda9da..97a5f61 100644 --- a/code/renderer/tr_bsp.cpp +++ b/code/renderer/tr_bsp.cpp @@ -224,11 +224,10 @@ static void R_LoadLightmaps( const lump_t* l ) } -static void R_GetLightmapTransform( int* number, vec2_t scale, vec2_t bias ) +static void R_GetLightmapTransform( int* number, vec2_t scale, vec2_t bias, qbool* isBrokenOut = NULL ) { const int i = *number; - - if ( i >= 0 ) { + if ( i >= 0 && i < MAX_LIGHTMAPS ) { scale[0] = lightmapScale[0]; scale[1] = lightmapScale[1]; bias[0] = lightmapBiases[i][0]; @@ -239,9 +238,16 @@ static void R_GetLightmapTransform( int* number, vec2_t scale, vec2_t bias ) scale[1] = 1.0f; bias[0] = 0.0f; bias[1] = 0.0f; - if ( *number <= LIGHTMAP_2D || *number >= tr.numLightmaps ) - *number = LIGHTMAP_BROKEN; } + + qbool isBroken = qfalse; + if ( *number <= LIGHTMAP_2D || *number >= tr.numLightmaps ) { + *number = LIGHTMAP_NONE; + isBroken = qtrue; + } + + if ( isBrokenOut != NULL ) + *isBrokenOut = isBroken; } @@ -333,8 +339,10 @@ static void ParseFace( const dsurface_t* ds, const drawVert_t* verts, msurface_t surf->fogIndex = LittleLong( ds->fogNum ) + 1; int lightmapNum = LittleLong( ds->lightmapNum ); vec2_t lmScale, lmBias; - R_GetLightmapTransform( &lightmapNum, lmScale, lmBias ); + qbool isLightmapBroken; + R_GetLightmapTransform( &lightmapNum, lmScale, lmBias, &isLightmapBroken ); shader_t* const shader = ShaderForShaderNum( ds->shaderNum, lightmapNum ); + shader->isLightmapBroken = isLightmapBroken; surf->shader = shader; R_SaveLightmapTransform( shader, lmScale, lmBias ); @@ -419,8 +427,10 @@ static void ParseMesh( const dsurface_t* ds, const drawVert_t* verts, msurface_t surf->fogIndex = LittleLong( ds->fogNum ) + 1; int lightmapNum = LittleLong(ds->lightmapNum); vec2_t lmScale, lmBias; - R_GetLightmapTransform( &lightmapNum, lmScale, lmBias ); + qbool isLightmapBroken; + R_GetLightmapTransform( &lightmapNum, lmScale, lmBias, &isLightmapBroken ); shader_t* const shader = ShaderForShaderNum( ds->shaderNum, lightmapNum ); + shader->isLightmapBroken = isLightmapBroken; surf->shader = shader; R_SaveLightmapTransform( shader, lmScale, lmBias ); diff --git a/code/renderer/tr_local.h b/code/renderer/tr_local.h index 343ef25..b7f92c4 100644 --- a/code/renderer/tr_local.h +++ b/code/renderer/tr_local.h @@ -323,7 +323,6 @@ typedef struct { } shaderStage_t; -#define LIGHTMAP_BROKEN -4 // invalid data in the .bsp file #define LIGHTMAP_2D -3 // shader is for 2D rendering #define LIGHTMAP_BY_VERTEX -2 // pre-lit triangle models #define LIGHTMAP_NONE -1 @@ -368,6 +367,7 @@ struct pipeline_t { struct shader_t { char name[MAX_QPATH]; // game path, including extension int lightmapIndex; // for a shader to match, both name and lightmapIndex must match + qbool isLightmapBroken; // was the lightmap index broken in the .bsp file? int index; // this shader == tr.shaders[index] int sortedIndex; // this shader == tr.sortedShaders[sortedIndex] diff --git a/code/renderer/tr_shader.cpp b/code/renderer/tr_shader.cpp index 6578e76..e7960e2 100644 --- a/code/renderer/tr_shader.cpp +++ b/code/renderer/tr_shader.cpp @@ -2792,9 +2792,9 @@ shader_t* R_FindShader( const char *name, int lightmapIndex, int flags ) stages[0].type = ST_DIFFUSE; stages[0].bundle.image[0] = image; - if ( shader.lightmapIndex == LIGHTMAP_BROKEN ) { - stages[0].rgbGen = CGEN_VERTEX; - stages[0].alphaGen = AGEN_VERTEX; + if ( shader.isLightmapBroken ) { + stages[0].rgbGen = CGEN_IDENTITY_LIGHTING; + stages[0].alphaGen = AGEN_SKIP; stages[0].stateBits = GLS_DEFAULT; } else if ( shader.lightmapIndex == LIGHTMAP_NONE ) { // dynamic colors at vertexes @@ -3024,12 +3024,13 @@ void R_ShaderInfo_f() const char* type; if ( sh->vlApplied ) { type = "vertex-lit surface"; + } else if ( sh->isLightmapBroken ) { + type = "broken lit surface"; } else { switch ( sh->lightmapIndex ) { - case LIGHTMAP_BROKEN: type = "broken lit surface"; break; - case LIGHTMAP_2D: type = "UI element"; break; - case LIGHTMAP_NONE: type = "opaque surface"; break; - default: type = "lit surface"; break; + case LIGHTMAP_2D: type = "UI element"; break; + case LIGHTMAP_NONE: type = "opaque surface"; break; + default: type = "lit surface"; break; } } ri.Printf( PRINT_ALL, "shader has no code (type: %s)\n", type );