Skip to content

Commit 8e9a33f

Browse files
committed
Allow shaders to be re-registered with different flags
Allow instantiating multiple versions of a q3shader if it was registered with different RSF_* flags each time. This will make it so that registering stuff in a different order will not give different behavior. NUKE shaderType_t and replace it with a new flag RSF_3D that replicates the behavior of the old shaderType_t::3D. Previously, shaders could be registered multiple times but only based on a differing shaderType_t.
1 parent ada0c98 commit 8e9a33f

File tree

7 files changed

+61
-93
lines changed

7 files changed

+61
-93
lines changed

src/engine/renderer/tr_bsp.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -829,7 +829,7 @@ static shader_t* ShaderForShaderNum( int shaderNum ) {
829829

830830
dshader_t* dsh = &s_worldData.shaders[shaderNum];
831831

832-
shader_t* shader = R_FindShader( dsh->shader, shaderType_t::SHADER_3D, RSF_DEFAULT );
832+
shader_t* shader = R_FindShader( dsh->shader, RSF_3D );
833833

834834
// If the shader had errors, just use default shader
835835
if ( shader->defaultShader ) {
@@ -3271,7 +3271,9 @@ static void R_LoadFogs( lump_t *l, lump_t *brushesLump, lump_t *sidesLump )
32713271
}
32723272

32733273
// get information from the shader for fog parameters
3274-
shader = R_FindShader( fogs->shader, shaderType_t::SHADER_3D, RSF_DEFAULT );
3274+
// it says RSF_3D but if there is no shader text found it should probably just error instead
3275+
// of trying to create an implicit shader from an image...
3276+
shader = R_FindShader( fogs->shader, RSF_3D );
32753277

32763278
out->fogParms = shader->fogParms;
32773279

src/engine/renderer/tr_local.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,10 @@ enum class ssaoMode {
10511051
struct Material;
10521052
struct MaterialSurface;
10531053

1054+
// [implicit only] enable lightmapping, front-side culling, disable (non-BSP) vertex colors, disable blending
1055+
// TODO(0.56): move to the public RegisterShaderFlags_t interface
1056+
#define RSF_3D ( BIT( 30 ) )
1057+
10541058
using stageRenderer_t = void(*)(shaderStage_t *);
10551059
using stageShaderBuildMarker_t = void(*)(const shaderStage_t*);
10561060
using surfaceDataUpdater_t = void(*)(uint32_t*, shaderStage_t*, bool, bool, bool);
@@ -1205,16 +1209,10 @@ enum class ssaoMode {
12051209
float depthForOpaque;
12061210
};
12071211

1208-
enum class shaderType_t
1209-
{
1210-
SHADER_2D, // surface material: shader is for 2D rendering (like GUI elements)
1211-
SHADER_3D,
1212-
};
1213-
12141212
struct shader_t
12151213
{
12161214
char name[ MAX_QPATH ]; // game path, including extension
1217-
shaderType_t type;
1215+
int registerFlags; // RSF_
12181216

12191217
int index; // this shader == tr.shaders[index]
12201218
int sortedIndex; // this shader == tr.sortedShaders[sortedIndex]
@@ -3103,7 +3101,7 @@ inline bool checkGLErrors()
31033101
qhandle_t RE_RegisterShader( const char *name, int flags );
31043102
qhandle_t RE_RegisterShaderFromImage( const char *name, image_t *image );
31053103

3106-
shader_t *R_FindShader( const char *name, shaderType_t type, int flags );
3104+
shader_t *R_FindShader( const char *name, int flags );
31073105
shader_t *R_GetShaderByHandle( qhandle_t hShader );
31083106
shader_t *R_FindShaderByName( const char *name );
31093107
const char *RE_GetShaderNameFromHandle( qhandle_t shader );

src/engine/renderer/tr_model_iqm.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -880,8 +880,8 @@ bool R_LoadIQModel( model_t *mod, const void *buffer, int filesize,
880880
surface->name = nullptr;
881881
}
882882

883-
surface->shader = R_FindShader( ( char* )IQMPtr(header, header->ofs_text + mesh->material),
884-
shaderType_t::SHADER_3D, RSF_DEFAULT );
883+
surface->shader = R_FindShader(
884+
( char* )IQMPtr(header, header->ofs_text + mesh->material), RSF_3D );
885885
if( surface->shader->defaultShader )
886886
surface->shader = tr.defaultShader;
887887
surface->data = IQModel;

src/engine/renderer/tr_model_md3.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ bool R_LoadMD3( model_t *mod, int lod, const void *buffer, const char *modName )
187187

188188
// only consider the first shader
189189
md3Shader = ( md3Shader_t * )( ( byte * ) md3Surf + md3Surf->ofsShaders );
190-
surf->shader = R_FindShader( md3Shader->name, shaderType_t::SHADER_3D, RSF_DEFAULT );
190+
surf->shader = R_FindShader( md3Shader->name, RSF_3D );
191191

192192
// swap all the triangles
193193
surf->numTriangles = md3Surf->numTriangles;

src/engine/renderer/tr_model_md5.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ bool R_LoadMD5( model_t *mod, const char *buffer, const char *modName )
317317
// lowercase the surface name so skin compares are faster
318318

319319
// register the shaders
320-
sh = R_FindShader( surf->shader, shaderType_t::SHADER_3D, RSF_DEFAULT );
320+
sh = R_FindShader( surf->shader, RSF_3D );
321321

322322
if ( sh->defaultShader )
323323
{

src/engine/renderer/tr_shader.cpp

Lines changed: 46 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -5833,7 +5833,7 @@ static shader_t *FinishShader()
58335833
numStages > 0 &&
58345834
(stages[0].stateBits & GLS_DEPTHMASK_TRUE) &&
58355835
!(stages[0].stateBits & GLS_DEPTHFUNC_EQUAL) &&
5836-
!(shader.type == shaderType_t::SHADER_2D) &&
5836+
!( shader.registerFlags & RSF_2D ) &&
58375837
!shader.polygonOffset ) {
58385838
// keep only the first stage
58395839
stages[1].active = false;
@@ -5920,7 +5920,7 @@ static shader_t *FinishShader()
59205920
if ( ret->altShader[ i ].name )
59215921
{
59225922
// flags were previously stashed in altShader[0].index
5923-
shader_t *sh = R_FindShader( ret->altShader[ i ].name, ret->type, (RegisterShaderFlags_t)ret->altShader[ 0 ].index );
5923+
shader_t *sh = R_FindShader( ret->altShader[ i ].name, ret->registerFlags );
59245924

59255925
ret->altShader[ i ].index = sh->defaultShader ? 0 : sh->index;
59265926
}
@@ -6018,17 +6018,16 @@ Will always return a valid shader, but it might be the
60186018
default shader if the real one can't be found.
60196019
60206020
In the interest of not requiring an explicit shader text entry to
6021-
be defined for every single image used in the game, two default
6022-
shader behaviors can be auto-created for any image that does not
6023-
have an explicit shader:
6024-
6025-
If type == SHADER_2D, then the image will default to using vertex colors.
6026-
6027-
If type == SHADER_3D, then the renderer will choose appropriate precomputed
6021+
be defined for every single image used in the game, shaders
6022+
can be auto-created for any image that does not
6023+
have an explicit shader. RSF_ flags like RSF_2D and RSF_3D
6024+
can influence the behaviors of these implicit shaders. For example
6025+
among other effects, RSF_3D will cause an implicit shader to use the
6026+
appropriate precomputed
60286027
lighting: lightmap, (precomputed) vertex or light grid.
60296028
===============
60306029
*/
6031-
shader_t *R_FindShader( const char *name, shaderType_t type, int flags )
6030+
shader_t *R_FindShader( const char *name, int flags )
60326031
{
60336032
char strippedName[ MAX_QPATH ];
60346033
char fileName[ MAX_QPATH ];
@@ -6042,21 +6041,30 @@ shader_t *R_FindShader( const char *name, shaderType_t type, int flags )
60426041
return tr.defaultShader;
60436042
}
60446043

6044+
// TODO(0.56): RSF_DEFAULT should be 0!
6045+
flags &= ~RSF_DEFAULT;
6046+
60456047
COM_StripExtension3( name, strippedName, sizeof( strippedName ) );
60466048

60476049
hash = generateHashValue( strippedName, FILE_HASH_SIZE );
60486050

60496051
// see if the shader is already loaded
60506052
for ( sh = shaderHashTable[ hash ]; sh; sh = sh->next )
60516053
{
6052-
// NOTE: if there was no shader or image available with the name strippedName
6053-
// then a default shader is created with type == SHADER_3D, so we
6054-
// have to check all default shaders otherwise for every call to R_FindShader
6055-
// with that same strippedName a new default shader is created.
6056-
if ( ( sh->type == type || sh->defaultShader ) && !Q_stricmp( sh->name, strippedName ) )
6054+
if ( !Q_stricmp( sh->name, strippedName ) )
60576055
{
6058-
// match found
6059-
return sh;
6056+
// NOTE: if there was no shader or image available with the name strippedName
6057+
// then a default shader is created, so we
6058+
// have to check all default shaders otherwise for every call to R_FindShader
6059+
// with that same strippedName a new default shader is created.
6060+
if ( sh->registerFlags == flags || sh->defaultShader )
6061+
{
6062+
// match found
6063+
return sh;
6064+
}
6065+
6066+
Log::Verbose( "shader %s registered with varying flags: previously with 0x%X, now with 0x%X",
6067+
strippedName, sh->registerFlags, flags );
60606068
}
60616069
}
60626070

@@ -6069,7 +6077,7 @@ shader_t *R_FindShader( const char *name, shaderType_t type, int flags )
60696077
ClearGlobalShader();
60706078

60716079
Q_strncpyz( shader.name, strippedName, sizeof( shader.name ) );
6072-
shader.type = type;
6080+
shader.registerFlags = flags;
60736081

60746082
for ( i = 0; i < MAX_SHADER_STAGES; i++ )
60756083
{
@@ -6079,13 +6087,14 @@ shader_t *R_FindShader( const char *name, shaderType_t type, int flags )
60796087
// ydnar: default to no implicit mappings
60806088
implicitMap[ 0 ] = '\0';
60816089
implicitStateBits = GLS_DEFAULT;
6082-
if( shader.type == shaderType_t::SHADER_2D )
6090+
6091+
if ( shader.registerFlags & RSF_3D )
60836092
{
6084-
implicitCullType = CT_TWO_SIDED;
6093+
implicitCullType = CT_FRONT_SIDED;
60856094
}
60866095
else
60876096
{
6088-
implicitCullType = CT_FRONT_SIDED;
6097+
implicitCullType = CT_TWO_SIDED;
60896098
}
60906099

60916100
if ( flags & RSF_NOMIP )
@@ -6191,32 +6200,22 @@ shader_t *R_FindShader( const char *name, shaderType_t type, int flags )
61916200
shader.cullType = implicitCullType;
61926201
}
61936202

6194-
// create the default shading commands
6195-
switch ( shader.type )
6203+
if ( flags & RSF_3D )
61966204
{
6197-
case shaderType_t::SHADER_2D:
6198-
{
6199-
// GUI elements
6200-
stages[ 0 ].bundle[ 0 ].image[ 0 ] = image;
6201-
stages[ 0 ].active = true;
6202-
stages[ 0 ].rgbGen = colorGen_t::CGEN_VERTEX;
6203-
stages[ 0 ].alphaGen = alphaGen_t::AGEN_VERTEX;
6204-
stages[ 0 ].stateBits = GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA;
6205-
break;
6206-
}
6207-
6208-
case shaderType_t::SHADER_3D:
6209-
{
6210-
stages[ 0 ].type = stageType_t::ST_COLLAPSE_DIFFUSEMAP;
6211-
stages[ 0 ].bundle[ 0 ].image[ 0 ] = image;
6212-
stages[ 0 ].active = true;
6213-
stages[ 0 ].rgbGen = colorGen_t::CGEN_IDENTITY;
6214-
stages[ 0 ].stateBits = implicitStateBits;
6215-
break;
6216-
}
6217-
6218-
default:
6219-
break;
6205+
stages[ 0 ].type = stageType_t::ST_COLLAPSE_DIFFUSEMAP;
6206+
stages[ 0 ].bundle[ 0 ].image[ 0 ] = image;
6207+
stages[ 0 ].active = true;
6208+
stages[ 0 ].rgbGen = colorGen_t::CGEN_IDENTITY;
6209+
stages[ 0 ].stateBits = implicitStateBits;
6210+
}
6211+
else
6212+
{
6213+
// preset appropriate for GUI elements
6214+
stages[ 0 ].bundle[ 0 ].image[ 0 ] = image;
6215+
stages[ 0 ].active = true;
6216+
stages[ 0 ].rgbGen = colorGen_t::CGEN_VERTEX;
6217+
stages[ 0 ].alphaGen = alphaGen_t::AGEN_VERTEX;
6218+
stages[ 0 ].stateBits = GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA;
62206219
}
62216220

62226221
return FinishShader();
@@ -6232,7 +6231,6 @@ qhandle_t RE_RegisterShaderFromImage( const char *name, image_t *image )
62326231
ClearGlobalShader();
62336232

62346233
Q_strncpyz( shader.name, name, sizeof( shader.name ) );
6235-
shader.type = shaderType_t::SHADER_2D;
62366234
shader.cullType = CT_TWO_SIDED;
62376235

62386236
for ( int i = 0; i < MAX_SHADER_STAGES; i++ )
@@ -6258,9 +6256,6 @@ RE_RegisterShader
62586256
62596257
This is the exported shader entry point for the rest of the system
62606258
It will always return an index that will be valid.
6261-
6262-
This should really only be used for explicit shaders, because there is no
6263-
way to ask for different implicit lighting modes (vertex, lightmap, etc)
62646259
====================
62656260
*/
62666261
qhandle_t RE_RegisterShader( const char *name, int flags )
@@ -6272,7 +6267,7 @@ qhandle_t RE_RegisterShader( const char *name, int flags )
62726267
return 0;
62736268
}
62746269

6275-
sh = R_FindShader( name, shaderType_t::SHADER_2D, flags );
6270+
sh = R_FindShader( name, flags );
62766271

62776272
// we want to return 0 if the shader failed to
62786273
// load for some reason, but R_FindShader should
@@ -6326,11 +6321,6 @@ class ListShadersCmd : public Cmd::StaticCmd
63266321

63276322
void Run( const Cmd::Args &args ) const override
63286323
{
6329-
static const std::unordered_map<shaderType_t, std::string> shaderTypeName = {
6330-
{ shaderType_t::SHADER_2D, "2D" },
6331-
{ shaderType_t::SHADER_3D, "3D" },
6332-
};
6333-
63346324
static const std::unordered_map<shaderSort_t, std::string> shaderSortName = {
63356325
{ shaderSort_t::SS_BAD, "BAD" },
63366326
{ shaderSort_t::SS_PORTAL, "PORTAL" },
@@ -6384,7 +6374,6 @@ class ListShadersCmd : public Cmd::StaticCmd
63846374

63856375
// Header names
63866376
std::string num = "num";
6387-
std::string shaderType = "shaderType";
63886377
std::string shaderSort = "shaderSort";
63896378
std::string stageType = "stageType";
63906379
std::string stageNumber = "stageNumber";
@@ -6395,15 +6384,10 @@ class ListShadersCmd : public Cmd::StaticCmd
63956384

63966385
// Header number sizes
63976386
numLen = std::max( numLen, num.length() );
6398-
size_t shaderTypeLen = shaderType.length();
63996387
size_t shaderSortLen = shaderSort.length();
64006388
size_t stageTypeLen = stageType.length();
64016389

64026390
// Value size
6403-
for ( const auto& kv : shaderTypeName )
6404-
{
6405-
shaderTypeLen = std::max( shaderTypeLen, kv.second.length() );
6406-
}
64076391

64086392
for ( const auto& kv : shaderSortName )
64096393
{
@@ -6421,7 +6405,6 @@ class ListShadersCmd : public Cmd::StaticCmd
64216405
// Print header
64226406
lineStream << std::left;
64236407
lineStream << std::setw(numLen) << num << separator;
6424-
lineStream << std::setw(shaderTypeLen) << shaderType << separator;
64256408
lineStream << std::setw(shaderSortLen) << shaderSort << separator;
64266409
lineStream << std::setw(stageTypeLen) << stageType << separator;
64276410
lineStream << stageNumber << ":" << shaderName;
@@ -6445,16 +6428,6 @@ class ListShadersCmd : public Cmd::StaticCmd
64456428
continue;
64466429
}
64476430

6448-
if ( !shaderTypeName.count( shader->type ) )
6449-
{
6450-
Log::Debug( "Undocumented shader type %i for shader %s",
6451-
Util::ordinal( shader->type ), shader->name );
6452-
}
6453-
else
6454-
{
6455-
shaderType = shaderTypeName.at( shader->type );
6456-
}
6457-
64586431
if ( !shaderSortName.count( (shaderSort_t) shader->sort ) )
64596432
{
64606433
Log::Debug( "Undocumented shader sort %f for shader %s",
@@ -6475,7 +6448,6 @@ class ListShadersCmd : public Cmd::StaticCmd
64756448

64766449
lineStream << std::left;
64776450
lineStream << std::setw(numLen) << i << separator;
6478-
lineStream << std::setw(shaderTypeLen) << shaderType << separator;
64796451
lineStream << std::setw(shaderSortLen) << shaderSort << separator;
64806452
lineStream << std::setw(stageTypeLen) << stageType << separator;
64816453
lineStream << "-:" << shaderName;
@@ -6507,7 +6479,6 @@ class ListShadersCmd : public Cmd::StaticCmd
65076479

65086480
lineStream << std::left;
65096481
lineStream << std::setw(numLen) << i << separator;
6510-
lineStream << std::setw(shaderTypeLen) << shaderType << separator;
65116482
lineStream << std::setw(shaderSortLen) << shaderSort << separator;
65126483
lineStream << std::setw(stageTypeLen) << stageType << separator;
65136484
lineStream << j << ":" << shaderName;
@@ -6800,7 +6771,6 @@ static void CreateInternalShaders()
68006771

68016772
Q_strncpyz( shader.name, "<default>", sizeof( shader.name ) );
68026773

6803-
shader.type = shaderType_t::SHADER_3D;
68046774
shader.noFog = true;
68056775
shader.fogShader = nullptr;
68066776
stages[ 0 ].type = stageType_t::ST_DIFFUSEMAP;
@@ -6811,7 +6781,6 @@ static void CreateInternalShaders()
68116781

68126782
Q_strncpyz( shader.name, "<fogEqual>", sizeof( shader.name ) );
68136783

6814-
shader.type = shaderType_t::SHADER_3D;
68156784
shader.sort = Util::ordinal( shaderSort_t::SS_FOG );
68166785
stages[0].type = stageType_t::ST_FOGMAP;
68176786
for ( int i = 0; i < 5; i++ ) {
@@ -6823,7 +6792,6 @@ static void CreateInternalShaders()
68236792

68246793
Q_strncpyz( shader.name, "<fogLE>", sizeof( shader.name ) );
68256794

6826-
shader.type = shaderType_t::SHADER_3D;
68276795
shader.sort = Util::ordinal( shaderSort_t::SS_FOG );
68286796
stages[0].type = stageType_t::ST_FOGMAP;
68296797
for ( int i = 0; i < 5; i++ ) {

src/engine/renderer/tr_skin.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ qhandle_t RE_RegisterSkin( const char *name )
261261
Q_strncpyz( surf->name, surfName, sizeof( surf->name ) );
262262

263263
// RB: bspSurface_t does not have ::hash yet
264-
surf->shader = R_FindShader( token, shaderType_t::SHADER_3D, RSF_DEFAULT );
264+
surf->shader = R_FindShader( token, RSF_3D );
265265
skin->numSurfaces++;
266266
}
267267

0 commit comments

Comments
 (0)