From: eihrul Date: Tue, 6 Oct 2009 19:24:41 +0000 (+0000) Subject: improved shadowmap side culling X-Git-Tag: xonotic-v0.1.0preview~1318 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=615c9db8a46177062894d229cd7afd5bd975f760;p=xonotic%2Fdarkplaces.git improved shadowmap side culling git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9316 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/client.h b/client.h index c6a347fa..d9fb6ab5 100644 --- a/client.h +++ b/client.h @@ -149,6 +149,9 @@ typedef struct rtlight_s /// (important on big surfaces such as terrain) int static_numlighttrispvsbytes; unsigned char *static_lighttrispvs; + /// masks of all shadowmap sides that have any potential static receivers or casters + int static_shadowmap_receivers; + int static_shadowmap_casters; } rtlight_t; diff --git a/gl_rsurf.c b/gl_rsurf.c index 867a82b2..f3f121ce 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -1064,18 +1064,21 @@ void R_Q1BSP_CompileShadowMap(entity_render_t *ent, vec3_t relativelightorigin, dp_model_t *model = ent->model; msurface_t *surface; int surfacelistindex; - int sidetotals[6] = { 0, 0, 0, 0, 0, 0 }; + int sidetotals[6] = { 0, 0, 0, 0, 0, 0 }, sidemasks = 0; + int i; 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++) { surface = model->data_surfaces + surfacelist[surfacelistindex]; - if (surface->texture->basematerialflags & MATERIALFLAG_NOSHADOW) - continue; - R_Shadow_ChooseSidesFromBox(surface->num_firstshadowmeshtriangle, surface->num_triangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, &r_shadow_compilingrtlight->matrix_worldtolight, relativelightorigin, relativelightdirection, r_shadow_compilingrtlight->cullmins, r_shadow_compilingrtlight->cullmaxs, surface->mins, surface->maxs, sidetotals); + sidemasks |= R_Shadow_ChooseSidesFromBox(surface->num_firstshadowmeshtriangle, surface->num_triangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, &r_shadow_compilingrtlight->matrix_worldtolight, relativelightorigin, relativelightdirection, r_shadow_compilingrtlight->cullmins, r_shadow_compilingrtlight->cullmaxs, surface->mins, surface->maxs, surface->texture->basematerialflags & MATERIALFLAG_NOSHADOW ? NULL : sidetotals); } R_Shadow_ShadowMapFromList(model->brush.shadowmesh->numverts, model->brush.shadowmesh->numtriangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, numshadowsides, sidetotals, shadowsides, shadowsideslist); r_shadow_compilingrtlight->static_meshchain_shadow_shadowmap = Mod_ShadowMesh_Finish(r_main_mempool, r_shadow_compilingrtlight->static_meshchain_shadow_shadowmap, false, false, true); + r_shadow_compilingrtlight->static_shadowmap_receivers &= sidemasks; + for(i = 0;i<6;i++) + if(!sidetotals[i]) + r_shadow_compilingrtlight->static_shadowmap_casters &= ~(1 << i); } void R_Q1BSP_DrawShadowMap(int side, entity_render_t *ent, const vec3_t relativelightorigin, const vec3_t relativelightdirection, float lightradius, int modelnumsurfaces, const int *modelsurfacelist, const vec3_t lightmins, const vec3_t lightmaxs) diff --git a/matrixlib.c b/matrixlib.c index 9ed67b59..73b8458a 100644 --- a/matrixlib.c +++ b/matrixlib.c @@ -147,7 +147,6 @@ void Matrix4x4_Transpose (matrix4x4_t *out, const matrix4x4_t *in1) int Matrix4x4_Invert_Full (matrix4x4_t *out, const matrix4x4_t *in1) { float det; - int i, j; // note: orientation does not matter, as transpose(invert(transpose(m))) == invert(m), proof: // transpose(invert(transpose(m))) * m diff --git a/r_shadow.c b/r_shadow.c index fa3ad8f7..38171250 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -1379,7 +1379,36 @@ int R_Shadow_CalcSphereSideMask(const vec3_t p, float radius, float bias) return mask; } -void R_Shadow_ChooseSidesFromBox(int firsttriangle, int numtris, const float *invertex3f, const int *elements, const matrix4x4_t *worldtolight, const vec3_t projectorigin, const vec3_t projectdirection, const vec3_t lightmins, const vec3_t lightmaxs, const vec3_t surfacemins, const vec3_t surfacemaxs, int *totals) +int R_Shadow_FrustumCullSides(rtlight_t *rtlight, float size, float border) +{ + static const vec3_t lightnormals[6] = { { 1, 0, 0 }, { -1, 0, 0 }, { 0, 1, 0 }, { 0, -1, 0 }, { 0, 0, 1 }, { 0, 0, -1 } }; + vec3_t frustumdir; + int i, j; + int sides = 0x3F; + // cos(45 + bias) + float scale = 0.707106781186548*(size - 2*border)/size; + for (i = 0;i < 5;i++) + { + if (PlaneDiff(rtlight->shadoworigin, &r_refdef.view.frustum[i]) > -0.03125) + continue; + Matrix4x4_Transform3x3(&rtlight->matrix_worldtolight, r_refdef.view.frustum[i].normal, frustumdir); + VectorNormalize(frustumdir); + for (j = 0;j < 6;j++) + if(DotProduct(frustumdir, lightnormals[j]) < -scale) + sides &= ~(1 << j); + } + if (PlaneDiff(rtlight->shadoworigin, &r_refdef.view.frustum[4]) > r_refdef.farclip - r_refdef.nearclip + 0.03125) + { + Matrix4x4_Transform3x3(&rtlight->matrix_worldtolight, r_refdef.view.frustum[4].normal, frustumdir); + VectorNormalize(frustumdir); + for (j = 0;j < 6;j++) + if (DotProduct(frustumdir, lightnormals[j]) > scale) + sides &= ~(1 << j); + } + return sides; +} + +int R_Shadow_ChooseSidesFromBox(int firsttriangle, int numtris, const float *invertex3f, const int *elements, const matrix4x4_t *worldtolight, const vec3_t projectorigin, const vec3_t projectdirection, const vec3_t lightmins, const vec3_t lightmaxs, const vec3_t surfacemins, const vec3_t surfacemaxs, int *totals) { int t, tend; const int *e; @@ -1387,9 +1416,9 @@ void R_Shadow_ChooseSidesFromBox(int firsttriangle, int numtris, const float *in float normal[3]; vec3_t p[3]; float bias; - unsigned char mask; + int mask, surfacemask = 0; if (!BoxesOverlap(lightmins, lightmaxs, surfacemins, surfacemaxs)) - return; + return 0; bias = r_shadow_shadowmapborder / (float)(r_shadow_shadowmapmaxsize - r_shadow_shadowmapborder); tend = firsttriangle + numtris; if (BoxInsideBox(surfacemins, surfacemaxs, lightmins, lightmaxs)) @@ -1405,9 +1434,13 @@ void R_Shadow_ChooseSidesFromBox(int firsttriangle, int numtris, const float *in { Matrix4x4_Transform(worldtolight, v[0], p[0]), Matrix4x4_Transform(worldtolight, v[1], p[1]), Matrix4x4_Transform(worldtolight, v[2], p[2]); mask = R_Shadow_CalcTriangleSideMask(p[0], p[1], p[2], bias); - totals[0] += mask&1, totals[1] += (mask>>1)&1, totals[2] += (mask>>2)&1, totals[3] += (mask>>3)&1, totals[4] += (mask>>4)&1, totals[5] += mask>>5; - shadowsides[numshadowsides] = mask; - shadowsideslist[numshadowsides++] = t; + surfacemask |= mask; + if(totals) + { + totals[0] += mask&1, totals[1] += (mask>>1)&1, totals[2] += (mask>>2)&1, totals[3] += (mask>>3)&1, totals[4] += (mask>>4)&1, totals[5] += mask>>5; + shadowsides[numshadowsides] = mask; + shadowsideslist[numshadowsides++] = t; + } } } } @@ -1420,9 +1453,13 @@ void R_Shadow_ChooseSidesFromBox(int firsttriangle, int numtris, const float *in { Matrix4x4_Transform(worldtolight, v[0], p[0]), Matrix4x4_Transform(worldtolight, v[1], p[1]), Matrix4x4_Transform(worldtolight, v[2], p[2]); mask = R_Shadow_CalcTriangleSideMask(p[0], p[1], p[2], bias); - totals[0] += mask&1, totals[1] += (mask>>1)&1, totals[2] += (mask>>2)&1, totals[3] += (mask>>3)&1, totals[4] += (mask>>4)&1, totals[5] += mask>>5; - shadowsides[numshadowsides] = mask; - shadowsideslist[numshadowsides++] = t; + surfacemask |= mask; + if(totals) + { + totals[0] += mask&1, totals[1] += (mask>>1)&1, totals[2] += (mask>>2)&1, totals[3] += (mask>>3)&1, totals[4] += (mask>>4)&1, totals[5] += mask>>5; + shadowsides[numshadowsides] = mask; + shadowsideslist[numshadowsides++] = t; + } } } } @@ -1441,9 +1478,13 @@ void R_Shadow_ChooseSidesFromBox(int firsttriangle, int numtris, const float *in { Matrix4x4_Transform(worldtolight, v[0], p[0]), Matrix4x4_Transform(worldtolight, v[1], p[1]), Matrix4x4_Transform(worldtolight, v[2], p[2]); mask = R_Shadow_CalcTriangleSideMask(p[0], p[1], p[2], bias); - totals[0] += mask&1, totals[1] += (mask>>1)&1, totals[2] += (mask>>2)&1, totals[3] += (mask>>3)&1, totals[4] += (mask>>4)&1, totals[5] += mask>>5; - shadowsides[numshadowsides] = mask; - shadowsideslist[numshadowsides++] = t; + surfacemask |= mask; + if(totals) + { + totals[0] += mask&1, totals[1] += (mask>>1)&1, totals[2] += (mask>>2)&1, totals[3] += (mask>>3)&1, totals[4] += (mask>>4)&1, totals[5] += mask>>5; + shadowsides[numshadowsides] = mask; + shadowsideslist[numshadowsides++] = t; + } } } } @@ -1457,13 +1498,18 @@ void R_Shadow_ChooseSidesFromBox(int firsttriangle, int numtris, const float *in { Matrix4x4_Transform(worldtolight, v[0], p[0]), Matrix4x4_Transform(worldtolight, v[1], p[1]), Matrix4x4_Transform(worldtolight, v[2], p[2]); mask = R_Shadow_CalcTriangleSideMask(p[0], p[1], p[2], bias); - totals[0] += mask&1, totals[1] += (mask>>1)&1, totals[2] += (mask>>2)&1, totals[3] += (mask>>3)&1, totals[4] += (mask>>4)&1, totals[5] += mask>>5; - shadowsides[numshadowsides] = mask; - shadowsideslist[numshadowsides++] = t; + surfacemask |= mask; + if(totals) + { + totals[0] += mask&1, totals[1] += (mask>>1)&1, totals[2] += (mask>>2)&1, totals[3] += (mask>>3)&1, totals[4] += (mask>>4)&1, totals[5] += mask>>5; + shadowsides[numshadowsides] = mask; + shadowsideslist[numshadowsides++] = t; + } } } } } + return surfacemask; } void R_Shadow_ShadowMapFromList(int numverts, int numtris, const float *vertex3f, const int *elements, int numsidetris, const int *sidetotals, const unsigned char *sides, const int *sidetris) @@ -3315,6 +3361,8 @@ void R_RTLight_Compile(rtlight_t *rtlight) rtlight->static_leafpvs = NULL; rtlight->static_numsurfaces = 0; rtlight->static_surfacelist = NULL; + rtlight->static_shadowmap_receivers = 0x3F; + rtlight->static_shadowmap_casters = 0x3F; rtlight->cullmins[0] = rtlight->shadoworigin[0] - rtlight->radius; rtlight->cullmins[1] = rtlight->shadoworigin[1] - rtlight->radius; rtlight->cullmins[2] = rtlight->shadoworigin[2] - rtlight->radius; @@ -3698,6 +3746,16 @@ void R_Shadow_DrawWorldShadow(int numsurfaces, int *surfacelist, const unsigned rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity } +static int R_Shadow_CalcEntitySideMask(rtlight_t *rtlight, entity_render_t *ent, float borderbias) +{ + vec3_t radius, worldorigin, lightorigin; + VectorSubtract(ent->maxs, ent->mins, radius); + VectorScale(radius, 0.5f, radius); + VectorAdd(ent->mins, radius, worldorigin); + Matrix4x4_Transform(&rtlight->matrix_worldtolight, worldorigin, lightorigin); + return R_Shadow_CalcSphereSideMask(lightorigin, VectorLength(radius) / rtlight->radius, borderbias); +} + void R_Shadow_DrawEntityShadow(entity_render_t *ent) { vec3_t relativeshadoworigin, relativeshadowmins, relativeshadowmaxs; @@ -3713,13 +3771,7 @@ void R_Shadow_DrawEntityShadow(entity_render_t *ent) relativeshadowmaxs[2] = relativeshadoworigin[2] + relativeshadowradius; if (r_shadow_rendermode == R_SHADOW_RENDERMODE_SHADOWMAPRECTANGLE || r_shadow_rendermode == R_SHADOW_RENDERMODE_SHADOWMAPCUBESIDE || r_shadow_rendermode == R_SHADOW_RENDERMODE_SHADOWMAP2D) { - vec3_t radius, worldorigin, lightorigin; - VectorSubtract(ent->maxs, ent->mins, radius); - VectorScale(radius, 0.5f, radius); - VectorAdd(ent->mins, radius, worldorigin); - Matrix4x4_Transform(&rsurface.rtlight->matrix_worldtolight, worldorigin, lightorigin); - if (R_Shadow_CalcSphereSideMask(lightorigin, VectorLength(radius) / relativeshadowradius, r_shadow_shadowmapborder / (float)(r_shadow_shadowmapsize - r_shadow_shadowmapborder)) & (1 << r_shadow_shadowmapside)) - ent->model->DrawShadowMap(r_shadow_shadowmapside, ent, relativeshadoworigin, NULL, relativeshadowradius, ent->model->nummodelsurfaces, ent->model->sortedmodelsurfaces, relativeshadowmins, relativeshadowmaxs); + ent->model->DrawShadowMap(r_shadow_shadowmapside, ent, relativeshadoworigin, NULL, relativeshadowradius, ent->model->nummodelsurfaces, ent->model->sortedmodelsurfaces, relativeshadowmins, relativeshadowmaxs); } else ent->model->DrawShadowVolume(ent, relativeshadoworigin, NULL, relativeshadowradius, ent->model->nummodelsurfaces, ent->model->sortedmodelsurfaces, relativeshadowmins, relativeshadowmaxs); @@ -3784,9 +3836,10 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible) int numshadowentities; int numshadowentities_noselfshadow; static entity_render_t *lightentities[MAX_EDICTS]; - static entity_render_t *lightentities_noselfshadow[MAX_EDICTS]; static entity_render_t *shadowentities[MAX_EDICTS]; - static entity_render_t *shadowentities_noselfshadow[MAX_EDICTS]; + static unsigned char entitysides[MAX_EDICTS]; + int lightentities_noselfshadow; + int shadowentities_noselfshadow; vec3_t nearestpoint; vec_t distance; qboolean castshadows; @@ -3889,8 +3942,11 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible) // make a list of lit entities and shadow casting entities numlightentities = 0; numlightentities_noselfshadow = 0; + lightentities_noselfshadow = sizeof(lightentities)/sizeof(lightentities[0]) - 1; numshadowentities = 0; numshadowentities_noselfshadow = 0; + shadowentities_noselfshadow = sizeof(shadowentities)/sizeof(shadowentities[0]) - 1; + // add dynamic entities that are lit by the light if (r_drawentities.integer) { @@ -3916,7 +3972,7 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible) if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.BoxTouchingLeafPVS && !r_refdef.scene.worldmodel->brush.BoxTouchingLeafPVS(r_refdef.scene.worldmodel, leafpvs, ent->mins, ent->maxs)) continue; if (ent->flags & RENDER_NOSELFSHADOW) - lightentities_noselfshadow[numlightentities_noselfshadow++] = ent; + lightentities[lightentities_noselfshadow - numlightentities_noselfshadow++] = ent; else lightentities[numlightentities++] = ent; // since it is lit, it probably also casts a shadow... @@ -3931,7 +3987,7 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible) // RENDER_NOSELFSHADOW entities such as the gun // (very weird, but keeps the player shadow off the gun) if (ent->flags & (RENDER_NOSELFSHADOW | RENDER_EXTERIORMODEL)) - shadowentities_noselfshadow[numshadowentities_noselfshadow++] = ent; + shadowentities[shadowentities_noselfshadow - numshadowentities_noselfshadow++] = ent; else shadowentities[numshadowentities++] = ent; } @@ -3949,7 +4005,7 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible) if ((ent->flags & RENDER_SHADOW) && model->DrawShadowVolume && VectorDistance2(org, rtlight->shadoworigin) > 0.1) { if (ent->flags & (RENDER_NOSELFSHADOW | RENDER_EXTERIORMODEL)) - shadowentities_noselfshadow[numshadowentities_noselfshadow++] = ent; + shadowentities[shadowentities_noselfshadow - numshadowentities_noselfshadow++] = ent; else shadowentities[numshadowentities++] = ent; } @@ -3980,7 +4036,7 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible) for (i = 0;i < numshadowentities;i++) R_Shadow_DrawEntityShadow(shadowentities[i]); for (i = 0;i < numshadowentities_noselfshadow;i++) - R_Shadow_DrawEntityShadow(shadowentities_noselfshadow[i]); + R_Shadow_DrawEntityShadow(shadowentities[shadowentities_noselfshadow - i]); } if (r_showlighting.integer && r_refdef.view.showdebug && numsurfaces + numlightentities + numlightentities_noselfshadow) @@ -3993,7 +4049,7 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible) for (i = 0;i < numlightentities;i++) R_Shadow_DrawEntityLight(lightentities[i]); for (i = 0;i < numlightentities_noselfshadow;i++) - R_Shadow_DrawEntityLight(lightentities_noselfshadow[i]); + R_Shadow_DrawEntityLight(lightentities[lightentities_noselfshadow - i]); } castshadows = numsurfaces + numshadowentities + numshadowentities_noselfshadow > 0 && rtlight->shadow && (rtlight->isstatic ? r_refdef.scene.rtworldshadows : r_refdef.scene.rtdlightshadows); @@ -4007,8 +4063,11 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible) if (castshadows && r_shadow_shadowmode >= 1 && r_shadow_shadowmode <= 3 && r_glsl.integer && gl_support_fragment_shader) { + float borderbias; int side; int size; + int castermask = 0; + int receivermask = 0; r_shadow_shadowmaplod = 0; for (i = 1;i < R_SHADOW_SHADOWMAP_NUMCUBEMAPS;i++) @@ -4017,16 +4076,47 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible) size = r_shadow_shadowmode == 3 ? r_shadow_shadowmapping_maxsize.integer >> r_shadow_shadowmaplod : lodlinear; size = bound(1, size, 2048); + borderbias = r_shadow_shadowmapborder / (float)(size - r_shadow_shadowmapborder); + + if (numsurfaces) + { + castermask = 0x3F; + receivermask = 0x3F; + if (rtlight->compiled && r_shadow_realtime_world_compile.integer && r_shadow_realtime_world_compileshadow.integer) + { + castermask &= rtlight->static_shadowmap_casters; + receivermask &= rtlight->static_shadowmap_receivers; + } + } + if (receivermask < 0x3F) + { + for (i = 0;i < numlightentities;i++) + receivermask |= R_Shadow_CalcEntitySideMask(rtlight, lightentities[i], borderbias); + if (receivermask < 0x3F) + for(i = 0; i < numlightentities_noselfshadow;i++) + receivermask |= R_Shadow_CalcEntitySideMask(rtlight, lightentities[lightentities_noselfshadow - i], borderbias); + } + + receivermask &= R_Shadow_FrustumCullSides(rtlight, size, r_shadow_shadowmapborder); + + if (receivermask) + { + for (i = 0;i < numshadowentities;i++) + castermask |= (entitysides[i] = R_Shadow_CalcEntitySideMask(rtlight, shadowentities[i], borderbias)); + for (i = 0;i < numshadowentities_noselfshadow;i++) + castermask |= (entitysides[shadowentities_noselfshadow - i] = R_Shadow_CalcEntitySideMask(rtlight, shadowentities[shadowentities_noselfshadow - i], borderbias)); + } //Con_Printf("distance %f lodlinear %i (lod %i) size %i\n", distance, lodlinear, r_shadow_shadowmaplod, size); // render shadow casters into 6 sided depth texture - for (side = 0;side < 6;side++) + for (side = 0;side < 6;side++) if (receivermask & (1 << side)) { R_Shadow_RenderMode_ShadowMap(side, true, size); + if (! (castermask & (1 << side))) continue; if (numsurfaces) R_Shadow_DrawWorldShadow_ShadowMap(numsurfaces, surfacelist, shadowtrispvs); - for (i = 0;i < numshadowentities;i++) + for (i = 0;i < numshadowentities;i++) if (entitysides[i] & (1 << side)) R_Shadow_DrawEntityShadow(shadowentities[i]); } @@ -4036,15 +4126,18 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible) // draw lighting in the unmasked areas R_Shadow_RenderMode_Lighting(false, false, true); for (i = 0;i < numlightentities_noselfshadow;i++) - R_Shadow_DrawEntityLight(lightentities_noselfshadow[i]); + R_Shadow_DrawEntityLight(lightentities[lightentities_noselfshadow - i]); } // render shadow casters into 6 sided depth texture - for (side = 0;side < 6;side++) + if (numshadowentities_noselfshadow) { - R_Shadow_RenderMode_ShadowMap(side, false, size); - for (i = 0;i < numshadowentities_noselfshadow;i++) - R_Shadow_DrawEntityShadow(shadowentities_noselfshadow[i]); + for (side = 0;side < 6;side++) if ((receivermask & castermask) & (1 << side)) + { + R_Shadow_RenderMode_ShadowMap(side, false, size); + for (i = 0;i < numshadowentities_noselfshadow;i++) if (entitysides[shadowentities_noselfshadow - i] && (1 << side)) + R_Shadow_DrawEntityShadow(shadowentities[shadowentities_noselfshadow - i]); + } } // render lighting using the depth texture as shadowmap @@ -4071,7 +4164,7 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible) // draw lighting in the unmasked areas R_Shadow_RenderMode_Lighting(true, false, false); for (i = 0;i < numlightentities_noselfshadow;i++) - R_Shadow_DrawEntityLight(lightentities_noselfshadow[i]); + R_Shadow_DrawEntityLight(lightentities[lightentities_noselfshadow - i]); // optionally draw the illuminated areas // for performance analysis by level designers @@ -4079,11 +4172,11 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible) { R_Shadow_RenderMode_VisibleLighting(!r_showdisabledepthtest.integer, false); for (i = 0;i < numlightentities_noselfshadow;i++) - R_Shadow_DrawEntityLight(lightentities_noselfshadow[i]); + R_Shadow_DrawEntityLight(lightentities[lightentities_noselfshadow - i]); } } for (i = 0;i < numshadowentities_noselfshadow;i++) - R_Shadow_DrawEntityShadow(shadowentities_noselfshadow[i]); + R_Shadow_DrawEntityShadow(shadowentities[shadowentities_noselfshadow - i]); if (numsurfaces + numlightentities) { @@ -4106,7 +4199,7 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible) for (i = 0;i < numlightentities;i++) R_Shadow_DrawEntityLight(lightentities[i]); for (i = 0;i < numlightentities_noselfshadow;i++) - R_Shadow_DrawEntityLight(lightentities_noselfshadow[i]); + R_Shadow_DrawEntityLight(lightentities[lightentities_noselfshadow - i]); } } } diff --git a/r_shadow.h b/r_shadow.h index b1347201..4ca6f021 100644 --- a/r_shadow.h +++ b/r_shadow.h @@ -44,7 +44,7 @@ void R_Shadow_ShadowMapFromList(int numverts, int numtris, const float *vertex3f void R_Shadow_MarkVolumeFromBox(int firsttriangle, int numtris, const float *invertex3f, const int *elements, const vec3_t projectorigin, const vec3_t projectdirection, const vec3_t lightmins, const vec3_t lightmaxs, const vec3_t surfacemins, const vec3_t surfacemaxs); int R_Shadow_CalcTriangleSideMask(const vec3_t p1, const vec3_t p2, const vec3_t p3, float bias); int R_Shadow_CalcSphereSideMask(const vec3_t p1, float radius, float bias); -void R_Shadow_ChooseSidesFromBox(int firsttriangle, int numtris, const float *invertex3f, const int *elements, const matrix4x4_t *worldtolight, const vec3_t projectorigin, const vec3_t projectdirection, const vec3_t lightmins, const vec3_t lightmaxs, const vec3_t surfacemins, const vec3_t surfacemaxs, int *totals); +int R_Shadow_ChooseSidesFromBox(int firsttriangle, int numtris, const float *invertex3f, const int *elements, const matrix4x4_t *worldtolight, const vec3_t projectorigin, const vec3_t projectdirection, const vec3_t lightmins, const vec3_t lightmaxs, const vec3_t surfacemins, const vec3_t surfacemaxs, int *totals); void R_Shadow_RenderLighting(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const unsigned short *element3s, int element3i_bufferobject, int element3s_bufferobject); void R_Shadow_RenderMode_Begin(void); void R_Shadow_RenderMode_ActiveLight(const rtlight_t *rtlight);