X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=gl_rsurf.c;h=0c9e85dc7ae6465f83d5ca0b0e6c4f01a2e92ebe;hb=d949ada62429d7c3ce992580c430ebc1cd916abf;hp=947f4146890d8ae5daf80642c759f723407e0d27;hpb=21ea7ca9acc5e13e563d00d7e9cd9e13e4dc7382;p=xonotic%2Fdarkplaces.git diff --git a/gl_rsurf.c b/gl_rsurf.c index 947f4146..0c9e85dc 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -53,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])) { @@ -446,7 +446,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++) @@ -486,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++) @@ -509,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++) @@ -524,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 @@ -540,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) @@ -548,20 +550,27 @@ 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; } } } @@ -637,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); @@ -645,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, false); if (ent == r_refdef.scene.worldentity) R_DrawWorldSurfaces(false, false, true, false, false); else @@ -696,6 +704,8 @@ typedef struct r_q1bsp_getlightinfo_s const unsigned char *pvs; qboolean svbsp_active; qboolean svbsp_insertoccluder; + qboolean noocclusion; // avoids PVS culling + qboolean frontsidecasting; // casts shadows from surfaces facing the light (otherwise ones facing away) int numfrustumplanes; const mplane_t *frustumplanes; } @@ -726,7 +736,8 @@ static void R_Q1BSP_RecursiveGetLightInfo_BSP(r_q1bsp_getlightinfo_t *info, qboo const vec_t *v[3]; float v2[3][3]; qboolean insidebox; - qboolean frontsidecasting = r_shadow_frontsidecasting.integer != 0; + qboolean noocclusion = info->noocclusion; + qboolean frontsidecasting = info->frontsidecasting; qboolean svbspactive = info->svbsp_active; qboolean svbspinsertoccluder = info->svbsp_insertoccluder; const int *leafsurfaceindices; @@ -767,13 +778,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]; } @@ -797,13 +808,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]; } @@ -816,7 +827,7 @@ static void R_Q1BSP_RecursiveGetLightInfo_BSP(r_q1bsp_getlightinfo_t *info, qboo // leaf leaf = (mleaf_t *)node; #if 1 - if (r_shadow_frontsidecasting.integer && info->pvs != NULL && !CHECKPVSBIT(info->pvs, leaf->clusterindex)) + if (!info->noocclusion && info->pvs != NULL && !CHECKPVSBIT(info->pvs, leaf->clusterindex)) continue; #endif #if 1 @@ -933,7 +944,7 @@ static void R_Q1BSP_RecursiveGetLightInfo_BSP(r_q1bsp_getlightinfo_t *info, qboo addedtris = true; if (castshadow) { - if (currentmaterialflags & MATERIALFLAG_NOCULLFACE) + if (noocclusion || (currentmaterialflags & MATERIALFLAG_NOCULLFACE)) { // if the material is double sided we // can't cull by direction @@ -975,6 +986,8 @@ static void R_Q1BSP_RecursiveGetLightInfo_BIH(r_q1bsp_getlightinfo_t *info, cons int nodeleafindex; int currentmaterialflags; qboolean castshadow; + qboolean noocclusion = info->noocclusion; + qboolean frontsidecasting = info->frontsidecasting; msurface_t *surface; const int *e; const vec_t *v[3]; @@ -1034,13 +1047,13 @@ static void R_Q1BSP_RecursiveGetLightInfo_BIH(r_q1bsp_getlightinfo_t *info, cons SETPVSBIT(info->outlighttrispvs, t); if (castshadow) { - if (currentmaterialflags & MATERIALFLAG_NOCULLFACE) + if (noocclusion || (currentmaterialflags & MATERIALFLAG_NOCULLFACE)) { // if the material is double sided we // can't cull by direction SETPVSBIT(info->outshadowtrispvs, t); } - else if (r_shadow_frontsidecasting.integer) + else if (frontsidecasting) { // front side casting occludes backfaces, // so they are completely useless as both @@ -1076,7 +1089,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; @@ -1197,9 +1210,11 @@ static int R_Q1BSP_GetLightInfo_comparefunc(const void *ap, const void *bp) extern cvar_t r_shadow_sortsurfaces; -void R_Q1BSP_GetLightInfo(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, vec3_t outmins, vec3_t outmaxs, int *outleaflist, unsigned char *outleafpvs, int *outnumleafspointer, int *outsurfacelist, unsigned char *outsurfacepvs, int *outnumsurfacespointer, unsigned char *outshadowtrispvs, unsigned char *outlighttrispvs, unsigned char *visitingleafpvs, int numfrustumplanes, const mplane_t *frustumplanes) +void R_Q1BSP_GetLightInfo(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, vec3_t outmins, vec3_t outmaxs, int *outleaflist, unsigned char *outleafpvs, int *outnumleafspointer, int *outsurfacelist, unsigned char *outsurfacepvs, int *outnumsurfacespointer, unsigned char *outshadowtrispvs, unsigned char *outlighttrispvs, unsigned char *visitingleafpvs, int numfrustumplanes, const mplane_t *frustumplanes, qboolean noocclusion) { r_q1bsp_getlightinfo_t info; + info.frontsidecasting = r_shadow_frontsidecasting.integer != 0; + info.noocclusion = noocclusion || !info.frontsidecasting; VectorCopy(relativelightorigin, info.relativelightorigin); info.lightradius = lightradius; info.lightmins[0] = info.relativelightorigin[0] - info.lightradius; @@ -1238,18 +1253,18 @@ void R_Q1BSP_GetLightInfo(entity_render_t *ent, vec3_t relativelightorigin, floa else memset(outshadowtrispvs, 0, (info.model->surfmesh.num_triangles + 7) >> 3); memset(outlighttrispvs, 0, (info.model->surfmesh.num_triangles + 7) >> 3); - if (info.model->brush.GetPVS && r_shadow_frontsidecasting.integer) + if (info.model->brush.GetPVS && !info.noocclusion) info.pvs = info.model->brush.GetPVS(info.model, info.relativelightorigin); else info.pvs = NULL; RSurf_ActiveWorldEntity(); - if (r_shadow_frontsidecasting.integer && r_shadow_compilingrtlight && r_shadow_realtime_world_compileportalculling.integer && info.model->brush.data_portals) + if (!info.noocclusion && r_shadow_compilingrtlight && r_shadow_realtime_world_compileportalculling.integer && info.model->brush.data_portals) { // use portal recursion for exact light volume culling, and exact surface checking Portal_Visibility(info.model, info.relativelightorigin, info.outleaflist, info.outleafpvs, &info.outnumleafs, info.outsurfacelist, info.outsurfacepvs, &info.outnumsurfaces, NULL, 0, true, info.lightmins, info.lightmaxs, info.outmins, info.outmaxs, info.outshadowtrispvs, info.outlighttrispvs, info.visitingleafpvs); } - else if (r_shadow_frontsidecasting.integer && r_shadow_realtime_dlight_portalculling.integer && info.model->brush.data_portals) + else if (!info.noocclusion && r_shadow_realtime_dlight_portalculling.integer && info.model->brush.data_portals) { // use portal recursion for exact light volume culling, but not the expensive exact surface checking Portal_Visibility(info.model, info.relativelightorigin, info.outleaflist, info.outleafpvs, &info.outnumleafs, info.outsurfacelist, info.outsurfacepvs, &info.outnumsurfaces, NULL, 0, r_shadow_realtime_dlight_portalculling.integer >= 2, info.lightmins, info.lightmaxs, info.outmins, info.outmaxs, info.outshadowtrispvs, info.outlighttrispvs, info.visitingleafpvs); @@ -1260,7 +1275,7 @@ void R_Q1BSP_GetLightInfo(entity_render_t *ent, vec3_t relativelightorigin, floa // optionally using svbsp for exact culling of compiled lights // (or if the user enables dlight svbsp culling, which is mostly for // debugging not actual use) - R_Q1BSP_CallRecursiveGetLightInfo(&info, (r_shadow_compilingrtlight ? r_shadow_realtime_world_compilesvbsp.integer : r_shadow_realtime_dlight_svbspculling.integer) != 0); + R_Q1BSP_CallRecursiveGetLightInfo(&info, !info.noocclusion && (r_shadow_compilingrtlight ? r_shadow_realtime_world_compilesvbsp.integer : r_shadow_realtime_dlight_svbspculling.integer) != 0); } rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity @@ -1404,8 +1419,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) @@ -1417,17 +1432,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 | BATCHNEED_ALLOWMULTIDRAW, 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); + R_Mesh_PrepareVertices_Vertex3f(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset); RSurf_DrawBatch(); } R_FrameData_ReturnToMark(); @@ -1444,7 +1456,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) { @@ -1613,7 +1625,7 @@ static 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); }