From: havoc Date: Sun, 30 Nov 2003 01:14:47 +0000 (+0000) Subject: now parses q3 shaders for surfaceparms (this mainly fixes up the many falsely transpa... X-Git-Tag: xonotic-v0.1.0preview~6251 X-Git-Url: https://git.xonotic.org/?a=commitdiff_plain;h=8c1397e484929df4b910a337ed9f227fc6c05a2c;p=xonotic%2Fdarkplaces.git now parses q3 shaders for surfaceparms (this mainly fixes up the many falsely transparent walls in shader tricks, and also detects nodraw shaders properly) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@3670 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/gl_rsurf.c b/gl_rsurf.c index 84a9a674..fc7a2c1c 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -2020,15 +2020,15 @@ void R_Q3BSP_DrawFace(entity_render_t *ent, q3mface_t *face) { if (!face->num_triangles) return; - if (face->texture->renderflags) + if (face->texture->surfaceparms) { - if (face->texture->renderflags & Q3MTEXTURERENDERFLAGS_SKY) + if (face->texture->surfaceparms & SURFACEPARM_SKY) return; - if (face->texture->renderflags & Q3MTEXTURERENDERFLAGS_NODRAW) + if (face->texture->surfaceparms & SURFACEPARM_NODRAW) return; } face->visframe = r_framecount; - if ((face->texture->renderflags & Q3MTEXTURERENDERFLAGS_TRANSPARENT) || ent->alpha < 1 || (ent->effects & EF_ADDITIVE)) + if ((face->texture->surfaceparms & SURFACEPARM_TRANS) || ent->alpha < 1 || (ent->effects & EF_ADDITIVE)) { vec3_t facecenter, center; facecenter[0] = (face->mins[0] + face->maxs[0]) * 0.5f; @@ -2110,12 +2110,12 @@ void R_Q3BSP_DrawSky(entity_render_t *ent) R_Q3BSP_RecursiveWorldNode(ent, model->brushq3.data_nodes, modelorg, pvs, r_framecount); } for (i = 0, face = model->brushq3.data_thismodel->firstface;i < model->brushq3.data_thismodel->numfaces;i++, face++) - if (face->markframe == r_framecount && (face->texture->renderflags & Q3MTEXTURERENDERFLAGS_SKY) && !R_CullBox(face->mins, face->maxs)) + if (face->markframe == r_framecount && (face->texture->surfaceparms & SURFACEPARM_SKY) && !R_CullBox(face->mins, face->maxs)) R_Q3BSP_DrawSkyFace(ent, face); } else for (i = 0, face = model->brushq3.data_thismodel->firstface;i < model->brushq3.data_thismodel->numfaces;i++, face++) - if ((face->texture->renderflags & Q3MTEXTURERENDERFLAGS_SKY)) + if ((face->texture->surfaceparms & SURFACEPARM_SKY)) R_Q3BSP_DrawSkyFace(ent, face); } } @@ -2191,7 +2191,7 @@ void R_Q3BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, void R_Q3BSP_DrawFaceLight(entity_render_t *ent, q3mface_t *face, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz) { - if ((face->texture->renderflags & Q3MTEXTURERENDERFLAGS_NODRAW) || !face->num_triangles) + if ((face->texture->surfaceparms & SURFACEPARM_NODRAW) || !face->num_triangles) return; R_Shadow_DiffuseLighting(face->num_vertices, face->num_triangles, face->data_element3i, face->data_vertex3f, face->data_svector3f, face->data_tvector3f, face->data_normal3f, face->data_texcoordtexture2f, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, face->texture->skin.base, face->texture->skin.nmap, NULL); R_Shadow_SpecularLighting(face->num_vertices, face->num_triangles, face->data_element3i, face->data_vertex3f, face->data_svector3f, face->data_tvector3f, face->data_normal3f, face->data_texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, face->texture->skin.gloss, face->texture->skin.nmap, NULL); diff --git a/model_brush.c b/model_brush.c index a8b6cd53..02408832 100644 --- a/model_brush.c +++ b/model_brush.c @@ -3308,7 +3308,12 @@ static void Mod_Q3BSP_LoadTextures(lump_t *l) { q3dtexture_t *in; q3mtexture_t *out; - int i, count; + int i, j, count, c; + fssearch_t *search; + char *f; + const char *text; + int flags; + char shadername[Q3PATHLENGTH]; in = (void *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) @@ -3319,10 +3324,6 @@ static void Mod_Q3BSP_LoadTextures(lump_t *l) loadmodel->brushq3.data_textures = out; loadmodel->brushq3.num_textures = count; - // FIXME: do a quick parse of the shader files to see if any names match - // up and get their surfaceparms - - for (i = 0;i < count;i++, in++, out++) { out->number = i; @@ -3331,15 +3332,151 @@ static void Mod_Q3BSP_LoadTextures(lump_t *l) out->nativecontents = LittleLong(in->contents); out->supercontents = Mod_Q3BSP_SuperContentsFromNativeContents(loadmodel, out->nativecontents); Mod_LoadSkinFrame(&out->skin, out->name, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, false, true, true); - out->renderflags = 0; - if (!strcmp(out->name, "caulk") || !strcmp(out->name, "common/caulk") || !strcmp(out->name, "textures/common/caulk") - || !strcmp(out->name, "nodraw") || !strcmp(out->name, "common/nodraw") || !strcmp(out->name, "textures/common/nodraw")) - out->renderflags |= Q3MTEXTURERENDERFLAGS_NODRAW; - if (!strncmp(out->name, "textures/skies/", 15)) - out->renderflags |= Q3MTEXTURERENDERFLAGS_SKY; - if (R_TextureHasAlpha(out->skin.base)) - out->renderflags |= Q3MTEXTURERENDERFLAGS_TRANSPARENT; + out->surfaceparms = -1; + } + + // do a quick parse of shader files to get surfaceparms + if ((search = FS_Search("scripts/*.shader", true, false))) + { + for (i = 0;i < search->numfilenames;i++) + { + if ((f = FS_LoadFile(search->filenames[i], false))) + { + text = f; + while (COM_ParseToken(&text, false)) + { + snprintf(shadername, sizeof(shadername), "%s", com_token); + flags = 0; + if (COM_ParseToken(&text, false) && !strcmp(com_token, "{")) + { + while (COM_ParseToken(&text, false)) + { + if (!strcmp(com_token, "}")) + break; + else if (!strcmp(com_token, "{")) + { + while (COM_ParseToken(&text, false)) + { + if (!strcmp(com_token, "}")) + break; + } + } + else if (!strcmp(com_token, "surfaceparm")) + { + if (COM_ParseToken(&text, true) && strcmp(com_token, "\n")) + { + if (!strcmp(com_token, "alphashadow")) + flags |= SURFACEPARM_ALPHASHADOW; + else if (!strcmp(com_token, "areaportal")) + flags |= SURFACEPARM_AREAPORTAL; + else if (!strcmp(com_token, "clusterportal")) + flags |= SURFACEPARM_CLUSTERPORTAL; + else if (!strcmp(com_token, "detail")) + flags |= SURFACEPARM_DETAIL; + else if (!strcmp(com_token, "donotenter")) + flags |= SURFACEPARM_DONOTENTER; + else if (!strcmp(com_token, "fog")) + flags |= SURFACEPARM_FOG; + else if (!strcmp(com_token, "lava")) + flags |= SURFACEPARM_LAVA; + else if (!strcmp(com_token, "lightfilter")) + flags |= SURFACEPARM_LIGHTFILTER; + else if (!strcmp(com_token, "metalsteps")) + flags |= SURFACEPARM_METALSTEPS; + else if (!strcmp(com_token, "nodamage")) + flags |= SURFACEPARM_NODAMAGE; + else if (!strcmp(com_token, "nodlight")) + flags |= SURFACEPARM_NODLIGHT; + else if (!strcmp(com_token, "nodraw")) + flags |= SURFACEPARM_NODRAW; + else if (!strcmp(com_token, "nodrop")) + flags |= SURFACEPARM_NODROP; + else if (!strcmp(com_token, "noimpact")) + flags |= SURFACEPARM_NOIMPACT; + else if (!strcmp(com_token, "nolightmap")) + flags |= SURFACEPARM_NOLIGHTMAP; + else if (!strcmp(com_token, "nomarks")) + flags |= SURFACEPARM_NOMARKS; + else if (!strcmp(com_token, "nomipmaps")) + flags |= SURFACEPARM_NOMIPMAPS; + else if (!strcmp(com_token, "nonsolid")) + flags |= SURFACEPARM_NONSOLID; + else if (!strcmp(com_token, "origin")) + flags |= SURFACEPARM_ORIGIN; + else if (!strcmp(com_token, "playerclip")) + flags |= SURFACEPARM_PLAYERCLIP; + else if (!strcmp(com_token, "sky")) + flags |= SURFACEPARM_SKY; + else if (!strcmp(com_token, "slick")) + flags |= SURFACEPARM_SLICK; + else if (!strcmp(com_token, "slime")) + flags |= SURFACEPARM_SLIME; + else if (!strcmp(com_token, "structural")) + flags |= SURFACEPARM_STRUCTURAL; + else if (!strcmp(com_token, "trans")) + flags |= SURFACEPARM_TRANS; + else if (!strcmp(com_token, "water")) + flags |= SURFACEPARM_WATER; + else + Con_Printf("%s parsing warning: unknown surfaceparm \"%s\"\n", search->filenames[i], com_token); + if (!COM_ParseToken(&text, true) || strcmp(com_token, "\n")) + { + Con_Printf("%s parsing error: surfaceparm only takes one parameter.\n", search->filenames[i]); + goto parseerror; + } + } + else + { + Con_Printf("%s parsing error: surfaceparm expects a parameter.\n", search->filenames[i]); + goto parseerror; + } + } + else + { + // look for linebreak or } + while(COM_ParseToken(&text, true) && strcmp(com_token, "\n") && strcmp(com_token, "}")); + // break out to top level if it was } + if (!strcmp(com_token, "}")) + break; + } + } + // add shader to list (shadername and flags) + // actually here we just poke into the texture settings + for (j = 0, out = loadmodel->brushq3.data_textures;j < loadmodel->brushq3.num_textures;j++, out++) + if (!strcmp(out->name, shadername)) + out->surfaceparms = flags; + } + else + { + Con_Printf("%s parsing error - expected \"{\", found \"%s\"\n", search->filenames[i], com_token); + goto parseerror; + } + } +parseerror: + Mem_Free(f); + } + } + } + + c = 0; + for (j = 0, out = loadmodel->brushq3.data_textures;j < loadmodel->brushq3.num_textures;j++, out++) + { + if (out->surfaceparms == -1) + { + c++; + Con_DPrintf("%s: No shader found for texture \"%s\"\n", loadmodel->name, out->name); + out->surfaceparms = 0; + // these are defaults + if (!strcmp(out->name, "caulk") || !strcmp(out->name, "common/caulk") || !strcmp(out->name, "textures/common/caulk") + || !strcmp(out->name, "nodraw") || !strcmp(out->name, "common/nodraw") || !strcmp(out->name, "textures/common/nodraw")) + out->surfaceparms |= SURFACEPARM_NODRAW; + if (!strncmp(out->name, "textures/skies/", 15)) + out->surfaceparms |= SURFACEPARM_SKY; + if (R_TextureHasAlpha(out->skin.base)) + out->surfaceparms |= SURFACEPARM_TRANS; + } } + Con_DPrintf("%s: %i textures missing shaders\n", loadmodel->name, c); } static void Mod_Q3BSP_LoadPlanes(lump_t *l) @@ -4680,7 +4817,7 @@ void Mod_Q3BSP_Load(model_t *mod, void *buffer) mod->radius2 = modelradius * modelradius; for (j = 0;j < mod->brushq3.data_thismodel->numfaces;j++) - if (mod->brushq3.data_thismodel->firstface[j].texture->renderflags & Q3MTEXTURERENDERFLAGS_SKY) + if (mod->brushq3.data_thismodel->firstface[j].texture->surfaceparms & SURFACEPARM_SKY) break; if (j < mod->brushq3.data_thismodel->numfaces) mod->DrawSky = R_Q3BSP_DrawSky; diff --git a/model_shared.h b/model_shared.h index 9d85080e..e1d63e99 100644 --- a/model_shared.h +++ b/model_shared.h @@ -279,9 +279,33 @@ typedef struct model_brushq2_s model_brushq2_t; */ -#define Q3MTEXTURERENDERFLAGS_NODRAW 1 -#define Q3MTEXTURERENDERFLAGS_SKY 2 -#define Q3MTEXTURERENDERFLAGS_TRANSPARENT 4 + +#define SURFACEPARM_ALPHASHADOW 1 +#define SURFACEPARM_AREAPORTAL 2 +#define SURFACEPARM_CLUSTERPORTAL 4 +#define SURFACEPARM_DETAIL 8 +#define SURFACEPARM_DONOTENTER 16 +#define SURFACEPARM_FOG 32 +#define SURFACEPARM_LAVA 64 +#define SURFACEPARM_LIGHTFILTER 128 +#define SURFACEPARM_METALSTEPS 256 +#define SURFACEPARM_NODAMAGE 512 +#define SURFACEPARM_NODLIGHT 1024 +#define SURFACEPARM_NODRAW 2048 +#define SURFACEPARM_NODROP 4096 +#define SURFACEPARM_NOIMPACT 8192 +#define SURFACEPARM_NOLIGHTMAP 16384 +#define SURFACEPARM_NOMARKS 32768 +#define SURFACEPARM_NOMIPMAPS 65536 +#define SURFACEPARM_NONSOLID 131072 +#define SURFACEPARM_ORIGIN 262144 +#define SURFACEPARM_PLAYERCLIP 524288 +#define SURFACEPARM_SKY 1048576 +#define SURFACEPARM_SLICK 2197152 +#define SURFACEPARM_SLIME 4194304 +#define SURFACEPARM_STRUCTURAL 8388608 +#define SURFACEPARM_TRANS 16777216 +#define SURFACEPARM_WATER 33554432 typedef struct q3mtexture_s { @@ -289,7 +313,7 @@ typedef struct q3mtexture_s int surfaceflags; int nativecontents; int supercontents; - int renderflags; + int surfaceparms; int number; skinframe_t skin; diff --git a/r_shadow.c b/r_shadow.c index 1826d96c..73725266 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -1877,12 +1877,12 @@ void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style if (face->lighttemp_castshadow) { face->lighttemp_castshadow = false; - if (!(face->texture->renderflags & (Q3MTEXTURERENDERFLAGS_NODRAW | Q3MTEXTURERENDERFLAGS_SKY))) + if (!(face->texture->surfaceparms & (SURFACEPARM_NODRAW | SURFACEPARM_SKY))) { if (e->castshadows) if (!(face->texture->nativecontents & CONTENTSQ3_TRANSLUCENT)) Mod_ShadowMesh_AddMesh(r_shadow_mempool, castmesh, NULL, NULL, NULL, face->data_vertex3f, NULL, NULL, NULL, NULL, face->num_triangles, face->data_element3i); - if (!(face->texture->renderflags & (Q3MTEXTURERENDERFLAGS_SKY))) + if (!(face->texture->surfaceparms & SURFACEPARM_SKY)) Mod_ShadowMesh_AddMesh(r_shadow_mempool, e->meshchain_light, face->texture->skin.base, face->texture->skin.gloss, face->texture->skin.nmap, face->data_vertex3f, face->data_svector3f, face->data_tvector3f, face->data_normal3f, face->data_texcoordtexture2f, face->num_triangles, face->data_element3i); } }