diff --git a/engine/client/renderer.c b/engine/client/renderer.c index 29894018d..87208460b 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -556,6 +556,7 @@ void Renderer_Init(void) #endif Cmd_AddCommand("r_dumpshaders", Shader_WriteOutGenerics_f); Cmd_AddCommand("r_remapshader", Shader_RemapShader_f); + Cmd_AddCommand("r_showshader", Shader_ShowShader_f); #if defined(GLQUAKE) || defined(D3DQUAKE) GLD3DRenderer_Init(); diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index 14a2a49c2..84c194217 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -168,17 +168,14 @@ static void Mod_TextureList_f(void) for (m=0 , mod=mod_known ; mtype == mod_brush && mod->loadstate == MLS_LOADED) { if (*mod->name == '*') continue;// inlines don't count - if (shownmodelname) - Con_Printf("%u\n", count); count = 0; - shownmodelname = false; for (i = 0; i < mod->numtextures; i++) { tx = mod->textures[i]; @@ -198,7 +195,7 @@ static void Mod_TextureList_f(void) } } if (shownmodelname) - Con_Printf("%u\n", count); + Con_Printf("(%u textures)\n", count); } static void Mod_BlockTextureColour_f (void) diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index 43d461d76..c885272bb 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -1995,117 +1995,104 @@ static struct static qboolean Shaderpass_MapGen (shader_t *shader, shaderpass_t *pass, char *tname) { + int tcgen = TC_GEN_BASE; if (!Q_stricmp (tname, "$lightmap")) { - pass->tcgen = TC_GEN_LIGHTMAP; + tcgen = TC_GEN_LIGHTMAP; pass->flags |= SHADER_PASS_LIGHTMAP | SHADER_PASS_NOMIPMAP; pass->texgen = T_GEN_LIGHTMAP; shader->flags |= SHADER_HASLIGHTMAP; } else if (!Q_stricmp (tname, "$deluxmap")) { - pass->tcgen = TC_GEN_LIGHTMAP; + tcgen = TC_GEN_LIGHTMAP; pass->flags |= SHADER_PASS_DELUXMAP | SHADER_PASS_NOMIPMAP; pass->texgen = T_GEN_DELUXMAP; } else if (!Q_stricmp (tname, "$diffuse")) { pass->texgen = T_GEN_DIFFUSE; - pass->tcgen = TC_GEN_BASE; } else if (!Q_stricmp (tname, "$normalmap")) { pass->texgen = T_GEN_NORMALMAP; - pass->tcgen = TC_GEN_BASE; shader->flags |= SHADER_HASNORMALMAP; } else if (!Q_stricmp (tname, "$specular")) { pass->texgen = T_GEN_SPECULAR; - pass->tcgen = TC_GEN_BASE; shader->flags |= SHADER_HASGLOSS; } else if (!Q_stricmp (tname, "$fullbright")) { pass->texgen = T_GEN_FULLBRIGHT; - pass->tcgen = TC_GEN_BASE; shader->flags |= SHADER_HASFULLBRIGHT; } else if (!Q_stricmp (tname, "$upperoverlay")) { shader->flags |= SHADER_HASTOPBOTTOM; pass->texgen = T_GEN_UPPEROVERLAY; - pass->tcgen = TC_GEN_BASE; } else if (!Q_stricmp (tname, "$loweroverlay")) { shader->flags |= SHADER_HASTOPBOTTOM; pass->texgen = T_GEN_LOWEROVERLAY; - pass->tcgen = TC_GEN_BASE; } else if (!Q_stricmp (tname, "$shadowmap")) { pass->texgen = T_GEN_SHADOWMAP; - pass->tcgen = TC_GEN_BASE; //FIXME: moo! pass->flags |= SHADER_PASS_DEPTHCMP; } else if (!Q_stricmp (tname, "$lightcubemap")) { pass->texgen = T_GEN_LIGHTCUBEMAP; - pass->tcgen = TC_GEN_BASE; //FIXME: moo! } else if (!Q_stricmp (tname, "$currentrender")) { pass->texgen = T_GEN_CURRENTRENDER; - pass->tcgen = TC_GEN_BASE; //FIXME: moo! } else if (!Q_stricmp (tname, "$sourcecolour")) { pass->texgen = T_GEN_SOURCECOLOUR; - pass->tcgen = TC_GEN_BASE; //FIXME: moo! } else if (!Q_stricmp (tname, "$sourcecube")) { pass->texgen = T_GEN_SOURCECUBE; - pass->tcgen = TC_GEN_BASE; //FIXME: moo! } else if (!Q_stricmp (tname, "$sourcedepth")) { pass->texgen = T_GEN_SOURCEDEPTH; - pass->tcgen = TC_GEN_BASE; //FIXME: moo! } else if (!Q_stricmp (tname, "$reflection")) { shader->flags |= SHADER_HASREFLECT; pass->texgen = T_GEN_REFLECTION; - pass->tcgen = TC_GEN_BASE; //FIXME: moo! } else if (!Q_stricmp (tname, "$refraction")) { shader->flags |= SHADER_HASREFRACT; pass->texgen = T_GEN_REFRACTION; - pass->tcgen = TC_GEN_BASE; //FIXME: moo! } else if (!Q_stricmp (tname, "$refractiondepth")) { shader->flags |= SHADER_HASREFRACT; pass->texgen = T_GEN_REFRACTIONDEPTH; - pass->tcgen = TC_GEN_BASE; //FIXME: moo! } else if (!Q_stricmp (tname, "$ripplemap")) { shader->flags |= SHADER_HASRIPPLEMAP; pass->texgen = T_GEN_RIPPLEMAP; - pass->tcgen = TC_GEN_BASE; //FIXME: moo! } else if (!Q_stricmp (tname, "$null")) { - pass->tcgen = TC_GEN_BASE; pass->flags |= SHADER_PASS_NOMIPMAP|SHADER_PASS_DETAIL; pass->texgen = T_GEN_SINGLEMAP; } else return false; + + if (pass->tcgen == TC_GEN_UNSPECIFIED) + pass->tcgen = tcgen; return true; } @@ -2133,7 +2120,8 @@ static void Shaderpass_Map (shader_t *shader, shaderpass_t *pass, char **ptr) break; } - pass->tcgen = TC_GEN_BASE; + if (pass->tcgen == TC_GEN_UNSPECIFIED) + pass->tcgen = TC_GEN_BASE; pass->anim_frames[0] = Shader_FindImage (token, flags); } } @@ -2146,7 +2134,8 @@ static void Shaderpass_AnimMap (shader_t *shader, shaderpass_t *pass, char **ptr flags = Shader_SetImageFlags (shader, pass, NULL); - pass->tcgen = TC_GEN_BASE; + if (pass->tcgen == TC_GEN_UNSPECIFIED) + pass->tcgen = TC_GEN_BASE; pass->flags |= SHADER_PASS_ANIMMAP; pass->texgen = T_GEN_ANIMMAP; pass->anim_fps = (int)Shader_ParseFloat (shader, ptr); @@ -2187,7 +2176,8 @@ static void Shaderpass_ClampMap (shader_t *shader, shaderpass_t *pass, char **pt flags = Shader_SetImageFlags (shader, pass, &token); if (!Shaderpass_MapGen(shader, pass, token)) { - pass->tcgen = TC_GEN_BASE; + if (pass->tcgen == TC_GEN_UNSPECIFIED) + pass->tcgen = TC_GEN_BASE; pass->anim_frames[0] = Shader_FindImage (token, flags | IF_CLAMP); switch((flags & IF_TEXTYPE) >> IF_TEXTYPESHIFT) @@ -3202,7 +3192,7 @@ void Shader_Readpass (shader_t *shader, char **ptr) pass->anim_numframes = 0; pass->rgbgen = RGB_GEN_UNKNOWN; pass->alphagen = ALPHA_GEN_IDENTITY; - pass->tcgen = TC_GEN_BASE; + pass->tcgen = TC_GEN_UNSPECIFIED; pass->numtcmods = 0; pass->numMergedPasses = 1; pass->stagetype = ST_AMBIENT; @@ -3274,6 +3264,9 @@ void Shader_Readpass (shader_t *shader, char **ptr) Con_Printf("if statements without endif in shader %s\n", shader->name); } + if (pass->tcgen == TC_GEN_UNSPECIFIED) + pass->tcgen = TC_GEN_BASE; + if (!ignore) { switch(pass->stagetype) @@ -4849,18 +4842,11 @@ qboolean Shader_ReadShaderTerms(shader_t *s, char **shadersource, int parsemode, //loads a shader string into an existing shader object, and finalises it and stuff static void Shader_ReadShader(shader_t *s, char *shadersource, int parsemode) { + char *shaderstart = shadersource; int conddepth = 0; int cond[8]; cond[0] = 0; - //querying the shader body often requires generating the shader, which then gets parsed. - if (saveshaderbody) - { - Z_Free(*saveshaderbody); - *saveshaderbody = Z_StrDup(shadersource); - saveshaderbody = NULL; - } - memset(&parsestate, 0, sizeof(parsestate)); parsestate.mode = parsemode; @@ -4878,6 +4864,17 @@ static void Shader_ReadShader(shader_t *s, char *shadersource, int parsemode) } Shader_Finish ( s ); + + //querying the shader body often requires generating the shader, which then gets parsed. + if (saveshaderbody) + { + size_t l = shadersource - shaderstart; + Z_Free(*saveshaderbody); + *saveshaderbody = BZ_Malloc(l+1); + (*saveshaderbody)[l] = 0; + memcpy(*saveshaderbody, shaderstart, l); + saveshaderbody = NULL; + } } static qboolean Shader_ParseShader(char *parsename, shader_t *s) @@ -5095,6 +5092,31 @@ char *Shader_GetShaderBody(shader_t *s) return adr; } +void Shader_ShowShader_f(void) +{ + char *sourcename = Cmd_Argv(1); + shader_t *o = R_LoadShader(sourcename, SUF_NONE, NULL, NULL); + if (!o) + o = R_LoadShader(sourcename, SUF_LIGHTMAP, NULL, NULL); + if (!o) + o = R_LoadShader(sourcename, SUF_2D, NULL, NULL); + if (o) + { + char *body = Shader_GetShaderBody(o); + if (body) + { + Con_Printf("%s\n{%s\n", o->name, body); + Z_Free(body); + } + else + { + Con_Printf("Shader \"%s\" is not in use\n", o->name); + } + } + else + Con_Printf("Shader \"%s\" is not loaded\n", sourcename); +} + void Shader_DoReload(void) { shader_t *s; diff --git a/engine/gl/shader.h b/engine/gl/shader.h index facb7d95f..044d66d1f 100644 --- a/engine/gl/shader.h +++ b/engine/gl/shader.h @@ -230,6 +230,8 @@ typedef struct shaderpass_s { TC_GEN_SKYBOX, TC_GEN_WOBBLESKY, TC_GEN_REFLECT, + + TC_GEN_UNSPECIFIED } tcgen; int numtcmods; tcmod_t tcmods[SHADER_MAX_TC_MODS]; @@ -268,7 +270,7 @@ typedef struct shaderpass_s { T_GEN_VIDEOMAP, //use the media playback as an image source, updating each frame for which it is visible T_GEN_CUBEMAP, //use a cubemap instead, otherwise like T_GEN_SINGLEMAP - T_GEN_3DMAP, //use a 3d texture instead, otherwise T_GEN_SINGLEMAP. + T_GEN_3DMAP //use a 3d texture instead, otherwise T_GEN_SINGLEMAP. } texgen; enum { @@ -590,6 +592,7 @@ qboolean Shader_Init (void); void Shader_NeedReload(qboolean rescanfs); void Shader_WriteOutGenerics_f(void); void Shader_RemapShader_f(void); +void Shader_ShowShader_f(void); mfog_t *Mod_FogForOrigin(model_t *wmodel, vec3_t org);