1
0
Fork 0
forked from fte/fteqw

------------------------------------------------------------------------

r4242 | acceptthis | 2013-03-08 02:45:46 +0000 (Fri, 08 Mar 2013) | 1 line

Change conditionals in shaders to properly support nested conditions and to be slightly more compatible with other engines (ie: qfusion/warsow). This refixes transparent water.
------------------------------------------------------------------------


git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4238 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2013-03-12 23:16:55 +00:00
parent 3ef2925cd8
commit c6b6c12a6e
4 changed files with 129 additions and 101 deletions

View file

@ -165,9 +165,8 @@ void R2D_Init(void)
draw_backtile = R_RegisterShader("gfx/backtile.lmp", draw_backtile = R_RegisterShader("gfx/backtile.lmp",
"{\n" "{\n"
"if $nofixed\n" "if $nofixed\n"
"[\n"
"program default2d\n" "program default2d\n"
"]\n" "endif\n"
"nomipmaps\n" "nomipmaps\n"
"{\n" "{\n"
"map $diffuse\n" "map $diffuse\n"
@ -247,26 +246,24 @@ void R2D_Init(void)
shader_menutint = R_RegisterShader("menutint", shader_menutint = R_RegisterShader("menutint",
"{\n" "{\n"
"if $glsl && gl_menutint_shader != 0\n" "if $glsl && gl_menutint_shader != 0\n"
"[\n"
"program menutint\n" "program menutint\n"
"{\n" "{\n"
"map $currentrender\n" "map $currentrender\n"
"}\n" "}\n"
"][\n" "else\n"
"{\n" "{\n"
"map $whiteimage\n" "map $whiteimage\n"
"blendfunc gl_dst_color gl_zero\n" "blendfunc gl_dst_color gl_zero\n"
"rgbgen const $r_menutint\n" "rgbgen const $r_menutint\n"
"}\n" "}\n"
"]\n" "endif\n"
"}\n" "}\n"
); );
shader_crosshair = R_RegisterShader("crosshairshader", shader_crosshair = R_RegisterShader("crosshairshader",
"{\n" "{\n"
"if $nofixed\n" "if $nofixed\n"
"[\n"
"program default2d\n" "program default2d\n"
"]\n" "endif\n"
"nomipmaps\n" "nomipmaps\n"
"{\n" "{\n"
"map $diffuse\n" "map $diffuse\n"
@ -457,9 +454,8 @@ void R2D_TransPicTranslate (int x, int y, int width, int height, qbyte *pic, qby
translate_texture = R_AllocNewTexture("***translatedpic***", 64, 64, 0); translate_texture = R_AllocNewTexture("***translatedpic***", 64, 64, 0);
translate_shader = R_RegisterShader("translatedpic", "{\n" translate_shader = R_RegisterShader("translatedpic", "{\n"
"if $nofixed\n" "if $nofixed\n"
"[\n"
"program default2d\n" "program default2d\n"
"]\n" "endif\n"
"nomipmaps\n" "nomipmaps\n"
"{\n" "{\n"
"map $diffuse\n" "map $diffuse\n"

View file

@ -267,9 +267,8 @@ void Font_Init(void)
fontplanes.shader = R_RegisterShader("ftefont", fontplanes.shader = R_RegisterShader("ftefont",
"{\n" "{\n"
"if $nofixed\n" "if $nofixed\n"
"[\n"
"program default2d\n" "program default2d\n"
"]\n" "endif\n"
"nomipmaps\n" "nomipmaps\n"
"{\n" "{\n"
"map $nearest:$diffuse\n" "map $nearest:$diffuse\n"

View file

@ -3221,9 +3221,8 @@ void Terr_FinishTerrain(heightmap_t *hm, char *shadername, char *skyname)
"}\n" "}\n"
"program terrain\n" "program terrain\n"
"if r_terraindebug\n" "if r_terraindebug\n"
"[\n"
"program terraindebug\n" "program terraindebug\n"
"]\n" "endif\n"
"}\n" "}\n"
); );

View file

@ -3238,6 +3238,11 @@ void Shader_Readpass (shader_t *shader, char **ptr)
shaderpass_t *pass; shaderpass_t *pass;
qboolean ignore; qboolean ignore;
static shader_t dummy; static shader_t dummy;
int conddepth = 0;
int cond[8] = {0};
#define COND_IGNORE 1
#define COND_IGNOREPARENT 2
#define COND_ALLOWELSE 4
if ( shader->numpasses >= SHADER_PASS_MAX ) if ( shader->numpasses >= SHADER_PASS_MAX )
{ {
@ -3273,45 +3278,62 @@ void Shader_Readpass (shader_t *shader, char **ptr)
{ {
continue; continue;
} }
else if ( token[0] == '}' )
{
break;
}
else if (!Q_stricmp(token, "if")) else if (!Q_stricmp(token, "if"))
{ {
int nest = 0; if (conddepth+1 == sizeof(cond)/sizeof(cond[0]))
qboolean conditionistrue = Shader_EvaluateCondition(shader, ptr);
while (*ptr)
{ {
token = COM_ParseExt (ptr, true, true); Con_Printf("if statements nest too deeply in shader %s\n", shader->name);
break;
}
conddepth++;
cond[conddepth] = (Shader_EvaluateCondition(shader, ptr)?0:COND_IGNORE);
cond[conddepth] |= COND_ALLOWELSE;
if (cond[conddepth-1] & (COND_IGNORE|COND_IGNOREPARENT))
cond[conddepth] |= COND_IGNOREPARENT;
}
else if (!Q_stricmp(token, "endif"))
{
if (!conddepth)
{
Con_Printf("endif without if in shader %s\n", shader->name);
break;
}
conddepth--;
}
else if (!Q_stricmp(token, "else"))
{
if (cond[conddepth] & COND_ALLOWELSE)
{
cond[conddepth] ^= COND_IGNORE;
cond[conddepth] &= ~COND_ALLOWELSE;
}
else
Con_Printf("unexpected else statement in shader %s\n", shader->name);
}
else if (cond[conddepth] & (COND_IGNORE|COND_IGNOREPARENT))
{
//eat it
while (ptr)
{
token = COM_ParseExt(ptr, false, true);
if ( !token[0] ) if ( !token[0] )
continue; break;
else if (token[0] == ']')
{
if (--nest <= 0)
{
nest++;
if (!strcmp(token, "]["))
conditionistrue = !conditionistrue;
else
break;
}
}
else if (token[0] == '[')
nest++;
else if (conditionistrue)
{
Shader_Parsetok (shader, pass, shaderpasskeys, token, ptr);
}
} }
} }
else if ( Shader_Parsetok (shader, pass, shaderpasskeys, token, ptr) ) else
{ {
break; if ( token[0] == '}' )
break;
else if ( Shader_Parsetok (shader, pass, shaderpasskeys, token, ptr) )
break;
} }
} }
if (conddepth)
{
Con_Printf("if statements without endif in shader %s\n", shader->name);
}
// check some things // check some things
if ( ignore ) if ( ignore )
{ {
@ -4133,7 +4155,6 @@ void Shader_DefaultBSPLM(char *shortname, shader_t *s, const void *args)
builtin = ( builtin = (
"{\n" "{\n"
/* "if $deluxmap\n" /* "if $deluxmap\n"
"[\n"
"{\n" "{\n"
"map $normalmap\n" "map $normalmap\n"
"tcgen base\n" "tcgen base\n"
@ -4143,34 +4164,30 @@ void Shader_DefaultBSPLM(char *shortname, shader_t *s, const void *args)
"map $deluxmap\n" "map $deluxmap\n"
"tcgen lightmap\n" "tcgen lightmap\n"
"}\n" "}\n"
"]\n" "endif\n"
*/// "if !r_fullbright\n" */// "if !r_fullbright\n"
// "[\n"
"{\n" "{\n"
"map $lightmap\n" "map $lightmap\n"
// "if $deluxmap\n" // "if $deluxmap\n"
// "[\n"
// "blendfunc gl_dst_color gl_zero\n" // "blendfunc gl_dst_color gl_zero\n"
// "]\n" // "endif\n"
"}\n" "}\n"
// "]\n" // "endif\n"
"{\n" "{\n"
"map $diffuse\n" "map $diffuse\n"
"tcgen base\n" "tcgen base\n"
// "if $deluxmap || !r_fullbright\n" // "if $deluxmap || !r_fullbright\n"
// "[\n"
// "blendfunc gl_dst_color gl_zero\n" // "blendfunc gl_dst_color gl_zero\n"
"blendfunc filter\n" "blendfunc filter\n"
// "]\n" // "endif\n"
"}\n" "}\n"
"if gl_fb_bmodels\n" "if gl_fb_bmodels\n"
"[\n"
"{\n" "{\n"
"map $fullbright\n" "map $fullbright\n"
"blendfunc add\n" "blendfunc add\n"
"depthfunc equal\n" "depthfunc equal\n"
"}\n" "}\n"
"]\n" "endif\n"
"}\n" "}\n"
); );
@ -4251,19 +4268,16 @@ char *Shader_DefaultBSPWater(char *shortname)
"map $diffuse\n" "map $diffuse\n"
"tcmod turb 0.02 0.1 0.5 0.1\n" "tcmod turb 0.02 0.1 0.5 0.1\n"
"if !$#ALPHA\n" "if !$#ALPHA\n"
"[\n"
"if r_wateralpha < 1\n" "if r_wateralpha < 1\n"
"[\n"
"alphagen const $r_wateralpha\n" "alphagen const $r_wateralpha\n"
"blendfunc gl_src_alpha gl_one_minus_src_alpha\n" "blendfunc gl_src_alpha gl_one_minus_src_alpha\n"
"]\n" "endif\n"
"][\n" "else\n"
"if $#ALPHA < 1\n" "if $#ALPHA < 1\n"
"[\n"
"alphagen const $#ALPHA\n" "alphagen const $#ALPHA\n"
"blendfunc gl_src_alpha gl_one_minus_src_alpha\n" "blendfunc gl_src_alpha gl_one_minus_src_alpha\n"
"]\n" "endif\n"
"]\n" "endif\n"
"}\n" "}\n"
"surfaceparm nodlight\n" "surfaceparm nodlight\n"
"}\n" "}\n"
@ -4479,7 +4493,6 @@ void Shader_DefaultBSPQ1(char *shortname, shader_t *s, const void *args)
builtin = ( builtin = (
"{\n" "{\n"
/* "if $deluxmap\n" /* "if $deluxmap\n"
"[\n"
"{\n" "{\n"
"map $normalmap\n" "map $normalmap\n"
"tcgen base\n" "tcgen base\n"
@ -4488,20 +4501,19 @@ void Shader_DefaultBSPQ1(char *shortname, shader_t *s, const void *args)
"map $deluxmap\n" "map $deluxmap\n"
"tcgen lightmap\n" "tcgen lightmap\n"
"}\n" "}\n"
"]\n"*/ "endif\n"*/
"{\n" "{\n"
"map $diffuse\n" "map $diffuse\n"
"tcgen base\n" "tcgen base\n"
"alphamask\n" "alphamask\n"
"}\n" "}\n"
"if $lightmap\n" "if $lightmap\n"
"[\n"
"{\n" "{\n"
"map $lightmap\n" "map $lightmap\n"
"blendfunc gl_dst_color gl_zero\n" "blendfunc gl_dst_color gl_zero\n"
"depthfunc equal\n" "depthfunc equal\n"
"}\n" "}\n"
"]\n" "endif\n"
"{\n" "{\n"
"map $fullbright\n" "map $fullbright\n"
"blendfunc add\n" "blendfunc add\n"
@ -4601,11 +4613,10 @@ void Shader_DefaultSkin(char *shortname, shader_t *s, const void *args)
Shader_DefaultScript(shortname, s, Shader_DefaultScript(shortname, s,
"{\n" "{\n"
"if $lpp\n" "if $lpp\n"
"[\n"
"program lpp_skin\n" "program lpp_skin\n"
"][\n" "else\n"
"program defaultskin\n" "program defaultskin\n"
"]\n" "endif\n"
"{\n" "{\n"
"map $diffuse\n" "map $diffuse\n"
"rgbgen lightingDiffuse\n" "rgbgen lightingDiffuse\n"
@ -4625,14 +4636,13 @@ void Shader_DefaultSkin(char *shortname, shader_t *s, const void *args)
"blendfunc add\n" "blendfunc add\n"
"}\n" "}\n"
"if $haveprogram\n" "if $haveprogram\n"
"[\n"
"{\n" "{\n"
"map $normalmap\n" "map $normalmap\n"
"}\n" "}\n"
"{\n" "{\n"
"map $specular\n" "map $specular\n"
"}\n" "}\n"
"]\n" "endif\n"
"}\n" "}\n"
); );
} }
@ -4656,9 +4666,8 @@ void Shader_Default2D(char *shortname, shader_t *s, const void *genargs)
Shader_DefaultScript(shortname, s, Shader_DefaultScript(shortname, s,
"{\n" "{\n"
"if $nofixed\n" "if $nofixed\n"
"[\n"
"program default2d\n" "program default2d\n"
"]\n" "endif\n"
"nomipmaps\n" "nomipmaps\n"
"{\n" "{\n"
"clampmap $diffuse\n" "clampmap $diffuse\n"
@ -4689,6 +4698,11 @@ void Shader_Default2D(char *shortname, shader_t *s, const void *genargs)
static void Shader_ReadShader(shader_t *s, char *shadersource, int parsemode) static void Shader_ReadShader(shader_t *s, char *shadersource, int parsemode)
{ {
char *token; char *token;
int conddepth = 0;
int cond[8] = {0};
#define COND_IGNORE 1
#define COND_IGNOREPARENT 2
#define COND_ALLOWELSE 4
shaderparsemode = parsemode; shaderparsemode = parsemode;
@ -4702,44 +4716,64 @@ static void Shader_ReadShader(shader_t *s, char *shadersource, int parsemode)
if ( !token[0] ) if ( !token[0] )
continue; continue;
else if ( token[0] == '}' )
break;
else if (!Q_stricmp(token, "if")) else if (!Q_stricmp(token, "if"))
{ {
int nest = 0; if (conddepth+1 == sizeof(cond)/sizeof(cond[0]))
qboolean conditionistrue = Shader_EvaluateCondition(s, &shadersource);
while (shadersource)
{ {
token = COM_ParseExt (&shadersource, true, true); Con_Printf("if statements nest too deeply in shader %s\n", s->name);
break;
}
conddepth++;
cond[conddepth] = (!Shader_EvaluateCondition(s, &shadersource)?COND_IGNORE:0);
cond[conddepth] |= COND_ALLOWELSE;
if (cond[conddepth-1] & (COND_IGNORE|COND_IGNOREPARENT))
cond[conddepth] |= COND_IGNOREPARENT;
}
else if (!Q_stricmp(token, "endif"))
{
if (!conddepth)
{
Con_Printf("endif without if in shader %s\n", s->name);
break;
}
conddepth--;
}
else if (!Q_stricmp(token, "else"))
{
if (cond[conddepth] & COND_ALLOWELSE)
{
cond[conddepth] ^= COND_IGNORE;
cond[conddepth] &= ~COND_ALLOWELSE;
}
else
Con_Printf("unexpected else statement in shader %s\n", s->name);
}
else if (cond[conddepth] & (COND_IGNORE|COND_IGNOREPARENT))
{
//eat it.
while (*shadersource)
{
token = COM_ParseExt(&shadersource, false, true);
if ( !token[0] ) if ( !token[0] )
continue;
else if (token[0] == ']')
{ {
if (--nest <= 0) break;
{
nest++;
if (!strcmp(token, "]["))
conditionistrue = !conditionistrue;
else
break;
}
}
else if (token[0] == '[')
nest++;
else if (conditionistrue)
{
if (token[0] == '{')
Shader_Readpass (s, &shadersource);
else
Shader_Parsetok (s, NULL, shaderkeys, token, &shadersource);
} }
} }
} }
else if ( token[0] == '{' ) else
Shader_Readpass ( s, &shadersource ); {
else if ( Shader_Parsetok (s, NULL, shaderkeys, token, &shadersource ) ) if (token[0] == '}')
break; break;
else if (token[0] == '{')
Shader_Readpass(s, &shadersource);
else if (Shader_Parsetok(s, NULL, shaderkeys, token, &shadersource))
break;
}
}
if (conddepth)
{
Con_Printf("if statements without endif in shader %s\n", s->name);
} }
Shader_Finish ( s ); Shader_Finish ( s );