Skip to content

Commit f30e76c

Browse files
committed
ParseShader: load extra textures the DarkPlaces way if r_dpMaterial on
if r_dpMaterial set to on, load extra textures the DarkPlaces way i.e. look for extra files with special suffixes like _norm or _gloss
1 parent 1e395e0 commit f30e76c

1 file changed

Lines changed: 125 additions & 0 deletions

File tree

src/engine/renderer/tr_shader.cpp

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,14 @@ static cullType_t implicitCullType;
4949

5050
static char whenTokens[ MAX_STRING_CHARS ];
5151

52+
// DarkPlaces material compatibility
53+
static Cvar::Cvar<bool> r_dpMaterial("r_dpMaterial", "Enable DarkPlaces material compatibility.", Cvar::NONE, false);
54+
55+
static bool UseDpMaterial()
56+
{
57+
return *r_dpMaterial;
58+
}
59+
5260
/*
5361
================
5462
return a hash value for the filename
@@ -1479,6 +1487,58 @@ static bool ParseClampType( char *token, wrapType_t *clamp )
14791487
return true;
14801488
}
14811489

1490+
/*
1491+
===================
1492+
FindMapInStage
1493+
===================
1494+
*/
1495+
static bool FindMapInStage( const char **text, char *buffer, int bufferlen )
1496+
{
1497+
char *token;
1498+
bool foundMap;
1499+
1500+
while ( true )
1501+
{
1502+
token = COM_ParseExt2( text, true );
1503+
1504+
if ( token[ 0 ] == '\0' )
1505+
{
1506+
// the real parser will complain about it
1507+
// no need to print twice the same warning
1508+
return false;
1509+
}
1510+
if ( token[ 0 ] == '}' )
1511+
{
1512+
break;
1513+
}
1514+
else if ( !Q_stricmp( token, "stage" ) )
1515+
{
1516+
return false;
1517+
}
1518+
else if ( !Q_stricmp( token, "map" ) )
1519+
{
1520+
if ( !ParseMap( text, buffer, bufferlen ) )
1521+
{
1522+
return false;
1523+
}
1524+
foundMap = true;
1525+
}
1526+
}
1527+
1528+
if ( foundMap )
1529+
{
1530+
if ( buffer[0] == '*'
1531+
|| buffer[0] == '_'
1532+
|| buffer[0] == '$' )
1533+
{
1534+
return false;
1535+
}
1536+
return true;
1537+
}
1538+
1539+
return false;
1540+
}
1541+
14821542
/*
14831543
===================
14841544
ParseStage
@@ -3100,6 +3160,22 @@ static void ParseLightFalloffImage( shaderStage_t *stage, const char **text )
31003160
}
31013161
}
31023162

3163+
struct extraMapParser_t
3164+
{
3165+
const char *suffix;
3166+
const char *description;
3167+
void ( *parser ) ( shaderStage_t*, const char** );
3168+
};
3169+
3170+
static const extraMapParser_t extraMapParsers[] =
3171+
{
3172+
{ "_norm", "normal map", ParseNormalMap },
3173+
{ "_gloss", "specular map", ParseSpecularMap },
3174+
{ "_glow", "glow map", ParseGlowMap },
3175+
};
3176+
3177+
static int numExtraMapParsers = ARRAY_LEN( extraMapParsers );
3178+
31033179
/*
31043180
=================
31053181
ParseShader
@@ -3144,6 +3220,55 @@ static bool ParseShader( const char *_text )
31443220
// stage definition
31453221
else if ( token[ 0 ] == '{' )
31463222
{
3223+
if ( UseDpMaterial() )
3224+
{
3225+
// DarkPlaces material compatibility
3226+
// look if the stage to be parsed has a map keyword without a stage keyword
3227+
// look for extra maps based on their suffixes
3228+
// if they exist, load them
3229+
// and tell the stage to be parsed is a diffuseMap one just before parsing it
3230+
const char **safeTextPointer;
3231+
const char *_safeTextPointer;
3232+
_safeTextPointer = *text;
3233+
safeTextPointer = &_safeTextPointer;
3234+
3235+
char colorMapName[ 1024 ] = "";
3236+
bool foundMap = FindMapInStage( safeTextPointer, colorMapName, sizeof( colorMapName ) );
3237+
if (foundMap) {
3238+
const char *prefix; // not used but required by R_FindImageLoader
3239+
const char *extraMapName;
3240+
char colorMapBaseName[ MAX_QPATH ];
3241+
bool foundExtraMap = false;
3242+
3243+
Log::Debug( "looking for extra maps for color map: '%s'", colorMapName );
3244+
COM_StripExtension3( colorMapName, colorMapBaseName, MAX_QPATH );
3245+
3246+
int i;
3247+
for ( i = 0; i < numExtraMapParsers; i++ )
3248+
{
3249+
if ( s >= ( MAX_SHADER_STAGES - 1 ) )
3250+
{
3251+
Log::Warn( "too many extra stages in shader %s", shader.name );
3252+
return false;
3253+
}
3254+
3255+
extraMapName = va( "%s%s", colorMapBaseName, extraMapParsers[ i ].suffix );
3256+
if( R_FindImageLoader( (char*) extraMapName, &prefix ) >= 0 )
3257+
{
3258+
foundExtraMap = true;
3259+
Log::Debug( "found extra %s '%s'", extraMapParsers[ i ].description, extraMapName );
3260+
extraMapParsers[ i ].parser( &stages[ s ], &extraMapName );
3261+
s++;
3262+
}
3263+
}
3264+
3265+
if ( foundExtraMap )
3266+
{
3267+
stages[ s ].type = stageType_t::ST_DIFFUSEMAP;
3268+
}
3269+
}
3270+
}
3271+
31473272
if ( s >= ( MAX_SHADER_STAGES - 1 ) )
31483273
{
31493274
Log::Warn("too many stages in shader %s", shader.name );

0 commit comments

Comments
 (0)