X-Git-Url: http://git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=gl_rsurf.c;h=72c5a472b936c48cc544512edc9739139af876e7;hp=967edc6f56e8a1778c593ebd3c4fab365d3835e3;hb=f5e4d031fd609e6a6ab36559e599211aa9ac51c3;hpb=9c19f5424cd24c82205885ed3d1c75f92f92b2d1 diff --git a/gl_rsurf.c b/gl_rsurf.c index 967edc6f..72c5a472 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -23,12 +23,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "r_shadow.h" #include "portals.h" #include "csprogs.h" +#include "image.h" cvar_t r_ambient = {0, "r_ambient", "0", "brightens map, value is 0-128"}; cvar_t r_lockpvs = {0, "r_lockpvs", "0", "disables pvs switching, allows you to walk around and inspect what is visible from a given location in the map (anything not visible from your current location will not be drawn)"}; cvar_t r_lockvisibility = {0, "r_lockvisibility", "0", "disables visibility updates, allows you to walk around and inspect what is visible from a given viewpoint in the map (anything offscreen at the moment this is enabled will not be drawn)"}; cvar_t r_useportalculling = {0, "r_useportalculling", "2", "improve framerate with r_novis 1 by using portal culling - still not as good as compiled visibility data in the map, but it helps (a value of 2 forces use of this even with vis data, which improves framerates in maps without too much complexity, but hurts in extremely complex maps, which is why 2 is not the default mode)"}; -cvar_t r_usesurfaceculling = {0, "r_usesurfaceculling", "1", "improve framerate by culling offscreen surfaces"}; +cvar_t r_usesurfaceculling = {0, "r_usesurfaceculling", "1", "skip off-screen surfaces (1 = cull surfaces if the map is likely to benefit, 2 = always cull surfaces)"}; cvar_t r_q3bsp_renderskydepth = {0, "r_q3bsp_renderskydepth", "0", "draws sky depth masking in q3 maps (as in q1 maps), this means for example that sky polygons can hide other things"}; /* @@ -52,8 +53,8 @@ void R_BuildLightMap (const entity_render_t *ent, msurface_t *surface) size = smax*tmax; size3 = size*3; - r_refdef.stats.lightmapupdatepixels += size; - r_refdef.stats.lightmapupdates++; + r_refdef.stats[r_stat_lightmapupdatepixels] += size; + r_refdef.stats[r_stat_lightmapupdates]++; if (cl.buildlightmapmemorysize < size*sizeof(int[3])) { @@ -120,6 +121,8 @@ void R_BuildLightMap (const entity_render_t *ent, msurface_t *surface) } } + if(vid_sRGB.integer && vid_sRGB_fallback.integer && !vid.sRGB3D) + Image_MakesRGBColorsFromLinear_Lightmap(templight, templight, size); R_UpdateTexture(surface->lightmaptexture, templight, surface->lightmapinfo->lightmaporigin[0], surface->lightmapinfo->lightmaporigin[1], 0, smax, tmax, 1); // update the surface's deluxemap if it has one @@ -162,7 +165,7 @@ void R_BuildLightMap (const entity_render_t *ent, msurface_t *surface) } } -void R_StainNode (mnode_t *node, dp_model_t *model, const vec3_t origin, float radius, const float fcolor[8]) +static void R_StainNode (mnode_t *node, dp_model_t *model, const vec3_t origin, float radius, const float fcolor[8]) { float ndist, a, ratio, maxdist, maxdist2, maxdist3, invradius, sdtable[256], td, dist2; msurface_t *surface, *endsurface; @@ -362,7 +365,7 @@ static void R_DrawPortal_Callback(const entity_render_t *ent, const rtlight_t *r for (i = 0, v = vertex3f;i < numpoints;i++, v += 3) VectorCopy(portal->points[i].position, v); R_Mesh_PrepareVertices_Generic_Arrays(numpoints, vertex3f, NULL, NULL); - R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, false); + R_SetupShader_Generic_NoTexture(false, false); R_Mesh_Draw(0, numpoints, 0, numpoints - 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0); } @@ -390,13 +393,36 @@ void R_DrawPortals(void) VectorAdd(center, portal->points[i].position, center); f = ixtable[portal->numpoints]; VectorScale(center, f, center); - R_MeshQueue_AddTransparent(center, R_DrawPortal_Callback, (entity_render_t *)portal, leafnum, rsurface.rtlight); + R_MeshQueue_AddTransparent(TRANSPARENTSORT_DISTANCE, center, R_DrawPortal_Callback, (entity_render_t *)portal, leafnum, rsurface.rtlight); } } } } } +static void R_View_WorldVisibility_CullSurfaces(void) +{ + int surfaceindex; + int surfaceindexstart; + int surfaceindexend; + unsigned char *surfacevisible; + msurface_t *surfaces; + dp_model_t *model = r_refdef.scene.worldmodel; + if (!model) + return; + if (r_trippy.integer) + return; + if (r_usesurfaceculling.integer < 1) + return; + surfaceindexstart = model->firstmodelsurface; + surfaceindexend = surfaceindexstart + model->nummodelsurfaces; + surfaces = model->data_surfaces; + surfacevisible = r_refdef.viewcache.world_surfacevisible; + for (surfaceindex = surfaceindexstart;surfaceindex < surfaceindexend;surfaceindex++) + if (surfacevisible[surfaceindex] && R_CullBox(surfaces[surfaceindex].mins, surfaces[surfaceindex].maxs)) + surfacevisible[surfaceindex] = 0; +} + void R_View_WorldVisibility(qboolean forcenovis) { int i, j, *mark; @@ -420,13 +446,14 @@ void R_View_WorldVisibility(qboolean forcenovis) // if leaf is in current pvs and on the screen, mark its surfaces if (CHECKPVSBIT(r_refdef.viewcache.world_pvsbits, leaf->clusterindex) && !R_CullBox(leaf->mins, leaf->maxs)) { - r_refdef.stats.world_leafs++; + r_refdef.stats[r_stat_world_leafs]++; r_refdef.viewcache.world_leafvisible[j] = true; if (leaf->numleafsurfaces) for (i = 0, mark = leaf->firstleafsurface;i < leaf->numleafsurfaces;i++, mark++) r_refdef.viewcache.world_surfacevisible[*mark] = true; } } + R_View_WorldVisibility_CullSurfaces(); return; } @@ -459,7 +486,7 @@ void R_View_WorldVisibility(qboolean forcenovis) // if leaf is in current pvs and on the screen, mark its surfaces if (!R_CullBox(leaf->mins, leaf->maxs)) { - r_refdef.stats.world_leafs++; + r_refdef.stats[r_stat_world_leafs]++; r_refdef.viewcache.world_leafvisible[j] = true; if (leaf->numleafsurfaces) for (i = 0, mark = leaf->firstleafsurface;i < leaf->numleafsurfaces;i++, mark++) @@ -482,7 +509,7 @@ void R_View_WorldVisibility(qboolean forcenovis) // if leaf is in current pvs and on the screen, mark its surfaces if (CHECKPVSBIT(r_refdef.viewcache.world_pvsbits, leaf->clusterindex) && !R_CullBox(leaf->mins, leaf->maxs)) { - r_refdef.stats.world_leafs++; + r_refdef.stats[r_stat_world_leafs]++; r_refdef.viewcache.world_leafvisible[j] = true; if (leaf->numleafsurfaces) for (i = 0, mark = leaf->firstleafsurface;i < leaf->numleafsurfaces;i++, mark++) @@ -497,6 +524,8 @@ void R_View_WorldVisibility(qboolean forcenovis) int leafstackpos; mportal_t *p; mleaf_t *leafstack[8192]; + vec3_t cullmins, cullmaxs; + float cullbias = r_nearclip.value * 2.0f; // the nearclip plane can easily end up culling portals in certain perfectly-aligned views, causing view blackouts // simple-frustum portal method: // follows portals leading outward from viewleaf, does not venture // offscreen or into leafs that are not visible, faster than @@ -513,7 +542,7 @@ void R_View_WorldVisibility(qboolean forcenovis) continue; if (leaf->clusterindex < 0) continue; - r_refdef.stats.world_leafs++; + r_refdef.stats[r_stat_world_leafs]++; r_refdef.viewcache.world_leafvisible[leaf - model->brush.data_leafs] = true; // mark any surfaces bounding this leaf if (leaf->numleafsurfaces) @@ -521,42 +550,33 @@ void R_View_WorldVisibility(qboolean forcenovis) r_refdef.viewcache.world_surfacevisible[*mark] = true; // follow portals into other leafs // the checks are: - // if viewer is behind portal (portal faces outward into the scene) - // and the portal polygon's bounding box is on the screen - // and the leaf has not been visited yet + // the leaf has not been visited yet // and the leaf is visible in the pvs - // (the first two checks won't cause as many cache misses as the leaf checks) + // the portal polygon's bounding box is on the screen for (p = leaf->portals;p;p = p->next) { - r_refdef.stats.world_portals++; - if (DotProduct(r_refdef.view.origin, p->plane.normal) < (p->plane.dist + 1) - && !r_refdef.viewcache.world_leafvisible[p->past - model->brush.data_leafs] - && CHECKPVSBIT(r_refdef.viewcache.world_pvsbits, p->past->clusterindex) - && !R_CullBox(p->mins, p->maxs) - && leafstackpos < (int)(sizeof(leafstack) / sizeof(leafstack[0]))) - leafstack[leafstackpos++] = p->past; + r_refdef.stats[r_stat_world_portals]++; + if (r_refdef.viewcache.world_leafvisible[p->past - model->brush.data_leafs]) + continue; + if (!CHECKPVSBIT(r_refdef.viewcache.world_pvsbits, p->past->clusterindex)) + continue; + cullmins[0] = p->mins[0] - cullbias; + cullmins[1] = p->mins[1] - cullbias; + cullmins[2] = p->mins[2] - cullbias; + cullmaxs[0] = p->maxs[0] + cullbias; + cullmaxs[1] = p->maxs[1] + cullbias; + cullmaxs[2] = p->maxs[2] + cullbias; + if (R_CullBox(cullmins, cullmaxs)) + continue; + if (leafstackpos >= (int)(sizeof(leafstack) / sizeof(leafstack[0]))) + break; + leafstack[leafstackpos++] = p->past; } } } } - if (r_usesurfaceculling.integer) - { - int k = model->firstmodelsurface; - int l = k + model->nummodelsurfaces; - unsigned char *visible = r_refdef.viewcache.world_surfacevisible; - msurface_t *surfaces = model->data_surfaces; - msurface_t *surface; - for (;k < l;k++) - { - if (visible[k]) - { - surface = surfaces + k; - if (R_CullBox(surface->mins, surface->maxs)) - visible[k] = false; - } - } -} + R_View_WorldVisibility_CullSurfaces(); } void R_Q1BSP_DrawSky(entity_render_t *ent) @@ -569,7 +589,6 @@ void R_Q1BSP_DrawSky(entity_render_t *ent) R_DrawModelSurfaces(ent, true, true, false, false, false); } -extern void R_Water_AddWaterPlane(msurface_t *surface, int entno); void R_Q1BSP_DrawAddWaterPlanes(entity_render_t *ent) { int i, j, n, flagsmask; @@ -581,7 +600,7 @@ void R_Q1BSP_DrawAddWaterPlanes(entity_render_t *ent) if (ent == r_refdef.scene.worldentity) RSurf_ActiveWorldEntity(); else - RSurf_ActiveModelEntity(ent, false, false, false); + RSurf_ActiveModelEntity(ent, true, false, false); surfaces = model->data_surfaces; flagsmask = MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA; @@ -627,7 +646,7 @@ void R_Q1BSP_Draw(entity_render_t *ent) void R_Q1BSP_DrawDepth(entity_render_t *ent) { dp_model_t *model = ent->model; - if (model == NULL) + if (model == NULL || model->surfmesh.isanimated) return; GL_ColorMask(0,0,0,0); GL_Color(1,1,1,1); @@ -635,7 +654,6 @@ void R_Q1BSP_DrawDepth(entity_render_t *ent) GL_BlendFunc(GL_ONE, GL_ZERO); GL_DepthMask(true); // R_Mesh_ResetTextureState(); - R_SetupShader_DepthOrShadow(false); if (ent == r_refdef.scene.worldentity) R_DrawWorldSurfaces(false, false, true, false, false); else @@ -757,13 +775,13 @@ static void R_Q1BSP_RecursiveGetLightInfo_BSP(r_q1bsp_getlightinfo_t *info, qboo // recurse front side first because the svbsp building prefers it if (info->relativelightorigin[plane->type] >= plane->dist) { - if (nodestackpos < GETLIGHTINFO_MAXNODESTACK) + if (nodestackpos < GETLIGHTINFO_MAXNODESTACK-1) nodestack[nodestackpos++] = node->children[0]; nodestack[nodestackpos++] = node->children[1]; } else { - if (nodestackpos < GETLIGHTINFO_MAXNODESTACK) + if (nodestackpos < GETLIGHTINFO_MAXNODESTACK-1) nodestack[nodestackpos++] = node->children[1]; nodestack[nodestackpos++] = node->children[0]; } @@ -787,13 +805,13 @@ static void R_Q1BSP_RecursiveGetLightInfo_BSP(r_q1bsp_getlightinfo_t *info, qboo // recurse front side first because the svbsp building prefers it if (PlaneDist(info->relativelightorigin, plane) >= 0) { - if (nodestackpos < GETLIGHTINFO_MAXNODESTACK) + if (nodestackpos < GETLIGHTINFO_MAXNODESTACK-1) nodestack[nodestackpos++] = node->children[0]; nodestack[nodestackpos++] = node->children[1]; } else { - if (nodestackpos < GETLIGHTINFO_MAXNODESTACK) + if (nodestackpos < GETLIGHTINFO_MAXNODESTACK-1) nodestack[nodestackpos++] = node->children[1]; nodestack[nodestackpos++] = node->children[0]; } @@ -884,7 +902,7 @@ static void R_Q1BSP_RecursiveGetLightInfo_BSP(r_q1bsp_getlightinfo_t *info, qboo VectorCopy(v[0], v2[0]); VectorCopy(v[1], v2[1]); VectorCopy(v[2], v2[2]); - if (insidebox || TriangleOverlapsBox(v2[0], v2[1], v2[2], info->lightmins, info->lightmaxs)) + if (insidebox || TriangleBBoxOverlapsBox(v2[0], v2[1], v2[2], info->lightmins, info->lightmaxs)) SVBSP_AddPolygon(&r_svbsp, 3, v2[0], true, NULL, NULL, 0); } } @@ -912,7 +930,7 @@ static void R_Q1BSP_RecursiveGetLightInfo_BSP(r_q1bsp_getlightinfo_t *info, qboo VectorCopy(v[0], v2[0]); VectorCopy(v[1], v2[1]); VectorCopy(v[2], v2[2]); - if (!insidebox && !TriangleOverlapsBox(v2[0], v2[1], v2[2], info->lightmins, info->lightmaxs)) + if (!insidebox && !TriangleBBoxOverlapsBox(v2[0], v2[1], v2[2], info->lightmins, info->lightmaxs)) continue; if (svbspactive && !(SVBSP_AddPolygon(&r_svbsp, 3, v2[0], false, NULL, NULL, 0) & 2)) continue; @@ -1066,7 +1084,7 @@ static void R_Q1BSP_RecursiveGetLightInfo_BIH(r_q1bsp_getlightinfo_t *info, cons #endif if (info->lightmins[axis] <= node->backmax) { - if (info->lightmaxs[axis] >= node->frontmin && nodestackpos < GETLIGHTINFO_MAXNODESTACK) + if (info->lightmaxs[axis] >= node->frontmin && nodestackpos < GETLIGHTINFO_MAXNODESTACK-1) nodestack[nodestackpos++] = node->front; nodestack[nodestackpos++] = node->back; continue; @@ -1172,7 +1190,7 @@ static void R_Q1BSP_CallRecursiveGetLightInfo(r_q1bsp_getlightinfo_t *info, qboo static msurface_t *r_q1bsp_getlightinfo_surfaces; -int R_Q1BSP_GetLightInfo_comparefunc(const void *ap, const void *bp) +static int R_Q1BSP_GetLightInfo_comparefunc(const void *ap, const void *bp) { int a = *(int*)ap; int b = *(int*)bp; @@ -1353,6 +1371,8 @@ void R_Q1BSP_CompileShadowMap(entity_render_t *ent, vec3_t relativelightorigin, int surfacelistindex; int sidetotals[6] = { 0, 0, 0, 0, 0, 0 }, sidemasks = 0; int i; + if (!model->brush.shadowmesh) + return; r_shadow_compilingrtlight->static_meshchain_shadow_shadowmap = Mod_ShadowMesh_Begin(r_main_mempool, 32768, 32768, NULL, NULL, NULL, false, false, true); R_Shadow_PrepareShadowSides(model->brush.shadowmesh->numtriangles); for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++) @@ -1392,8 +1412,8 @@ void R_Q1BSP_DrawShadowMap(int side, entity_render_t *ent, const vec3_t relative continue; if (!BoxesOverlap(lightmins, lightmaxs, surface->mins, surface->maxs)) continue; - r_refdef.stats.lights_dynamicshadowtriangles += surface->num_triangles; - r_refdef.stats.lights_shadowtriangles += surface->num_triangles; + r_refdef.stats[r_stat_lights_dynamicshadowtriangles] += surface->num_triangles; + r_refdef.stats[r_stat_lights_shadowtriangles] += surface->num_triangles; batchsurfacelist[0] = surface; batchnumsurfaces = 1; while(++modelsurfacelistindex < modelnumsurfaces && batchnumsurfaces < RSURF_MAX_BATCHSURFACES) @@ -1405,17 +1425,14 @@ void R_Q1BSP_DrawShadowMap(int side, entity_render_t *ent, const vec3_t relative break; if (!BoxesOverlap(lightmins, lightmaxs, surface->mins, surface->maxs)) continue; - r_refdef.stats.lights_dynamicshadowtriangles += surface->num_triangles; - r_refdef.stats.lights_shadowtriangles += surface->num_triangles; + r_refdef.stats[r_stat_lights_dynamicshadowtriangles] += surface->num_triangles; + r_refdef.stats[r_stat_lights_shadowtriangles] += surface->num_triangles; batchsurfacelist[batchnumsurfaces++] = surface; } --modelsurfacelistindex; GL_CullFace(rsurface.texture->currentmaterialflags & MATERIALFLAG_NOCULLFACE ? GL_NONE : r_refdef.view.cullface_back); - RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX, batchnumsurfaces, batchsurfacelist); - if (rsurface.batchvertex3fbuffer) - R_Mesh_PrepareVertices_Vertex3f(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchvertex3fbuffer); - else - R_Mesh_PrepareVertices_Vertex3f(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer); + RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ALLOWMULTIDRAW, batchnumsurfaces, batchsurfacelist); + R_Mesh_PrepareVertices_Vertex3f(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset); RSurf_DrawBatch(); } R_FrameData_ReturnToMark(); @@ -1432,7 +1449,7 @@ static void R_Q1BSP_DrawLight_TransparentCallback(const entity_render_t *ent, co // note: in practice this never actually receives batches R_Shadow_RenderMode_Begin(); R_Shadow_RenderMode_ActiveLight(rtlight); - R_Shadow_RenderMode_Lighting(false, true, false); + R_Shadow_RenderMode_Lighting(false, true, rtlight->shadowmapatlassidesize != 0, (ent->flags & RENDER_NOSELFSHADOW) != 0); R_Shadow_SetupEntityLight(ent); for (i = 0;i < numsurfaces;i = j) { @@ -1494,9 +1511,9 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, int numsurfaces, const int *surface ; // now figure out what to do with this particular range of surfaces // VorteX: added MATERIALFLAG_NORTLIGHT - if ((rsurface.texture->currentmaterialflags & (MATERIALFLAG_WALL + MATERIALFLAG_NORTLIGHT)) != MATERIALFLAG_WALL) + if ((rsurface.texture->currentmaterialflags & (MATERIALFLAG_WALL | MATERIALFLAG_FULLBRIGHT | MATERIALFLAG_NORTLIGHT)) != MATERIALFLAG_WALL) continue; - if (r_waterstate.renderingscene && (rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA))) + if (r_fb.water.renderingscene && (rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA))) continue; if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) { @@ -1504,11 +1521,26 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, int numsurfaces, const int *surface for (l = k;l < kend;l++) { surface = batchsurfacelist[l]; - tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f; - tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f; - tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f; + if (r_transparent_sortsurfacesbynearest.integer) + { + tempcenter[0] = bound(surface->mins[0], rsurface.localvieworigin[0], surface->maxs[0]); + tempcenter[1] = bound(surface->mins[1], rsurface.localvieworigin[1], surface->maxs[1]); + tempcenter[2] = bound(surface->mins[2], rsurface.localvieworigin[2], surface->maxs[2]); + } + else + { + tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f; + tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f; + tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f; + } Matrix4x4_Transform(&rsurface.matrix, tempcenter, center); - R_MeshQueue_AddTransparent(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_refdef.view.origin : center, R_Q1BSP_DrawLight_TransparentCallback, ent, surface - rsurface.modelsurfaces, rsurface.rtlight); + if (ent->transparent_offset) // transparent offset + { + center[0] += r_refdef.view.forward[0]*ent->transparent_offset; + center[1] += r_refdef.view.forward[1]*ent->transparent_offset; + center[2] += r_refdef.view.forward[2]*ent->transparent_offset; + } + R_MeshQueue_AddTransparent((rsurface.entity->flags & RENDER_WORLDOBJECT) ? TRANSPARENTSORT_SKY : ((rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST) ? TRANSPARENTSORT_HUD : rsurface.texture->transparentsort), center, R_Q1BSP_DrawLight_TransparentCallback, ent, surface - rsurface.modelsurfaces, rsurface.rtlight); } continue; } @@ -1523,7 +1555,7 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, int numsurfaces, const int *surface } //Made by [515] -void R_ReplaceWorldTexture (void) +static void R_ReplaceWorldTexture (void) { dp_model_t *m; texture_t *t; @@ -1559,7 +1591,6 @@ void R_ReplaceWorldTexture (void) if ((skinframe = R_SkinFrame_LoadExternal(newt, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PICMIP, true))) { // t->skinframes[0] = skinframe; - t->currentskinframe = skinframe; t->currentskinframe = skinframe; Con_Printf("%s replaced with %s\n", r, newt); } @@ -1573,7 +1604,7 @@ void R_ReplaceWorldTexture (void) } //Made by [515] -void R_ListWorldTextures (void) +static void R_ListWorldTextures (void) { dp_model_t *m; texture_t *t; @@ -1587,7 +1618,7 @@ void R_ListWorldTextures (void) Con_Print("Worldmodel textures :\n"); for(i=0,t=m->data_textures;inum_textures;i++,t++) - if (t->numskinframes) + if (t->name[0] && strcasecmp(t->name, "NO TEXTURE FOUND")) Con_Printf("%s\n", t->name); }