+#endif
+
+#if 0
+ // add the world-space reduced box planes
+ for (i = 0;i < 6;i++)
+ {
+ VectorClear(plane.normal);
+ plane.normal[i >> 1] = (i & 1) ? -1 : 1;
+ plane.dist = (i & 1) ? -r_shadow_rtlight_cullmaxs[i >> 1] : r_shadow_rtlight_cullmins[i >> 1];
+ r_shadow_rtlight_frustumplanes[r_shadow_rtlight_numfrustumplanes++] = plane;
+ }
+#endif
+
+#if 0
+ {
+ int j, oldnum;
+ vec3_t points[8];
+ vec_t bestdist;
+ // reduce all plane distances to tightly fit the rtlight cull box, which
+ // is in worldspace
+ VectorSet(points[0], r_shadow_rtlight_cullmins[0], r_shadow_rtlight_cullmins[1], r_shadow_rtlight_cullmins[2]);
+ VectorSet(points[1], r_shadow_rtlight_cullmaxs[0], r_shadow_rtlight_cullmins[1], r_shadow_rtlight_cullmins[2]);
+ VectorSet(points[2], r_shadow_rtlight_cullmins[0], r_shadow_rtlight_cullmaxs[1], r_shadow_rtlight_cullmins[2]);
+ VectorSet(points[3], r_shadow_rtlight_cullmaxs[0], r_shadow_rtlight_cullmaxs[1], r_shadow_rtlight_cullmins[2]);
+ VectorSet(points[4], r_shadow_rtlight_cullmins[0], r_shadow_rtlight_cullmins[1], r_shadow_rtlight_cullmaxs[2]);
+ VectorSet(points[5], r_shadow_rtlight_cullmaxs[0], r_shadow_rtlight_cullmins[1], r_shadow_rtlight_cullmaxs[2]);
+ VectorSet(points[6], r_shadow_rtlight_cullmins[0], r_shadow_rtlight_cullmaxs[1], r_shadow_rtlight_cullmaxs[2]);
+ VectorSet(points[7], r_shadow_rtlight_cullmaxs[0], r_shadow_rtlight_cullmaxs[1], r_shadow_rtlight_cullmaxs[2]);
+ oldnum = r_shadow_rtlight_numfrustumplanes;
+ r_shadow_rtlight_numfrustumplanes = 0;
+ for (j = 0;j < oldnum;j++)
+ {
+ // find the nearest point on the box to this plane
+ bestdist = DotProduct(r_shadow_rtlight_frustumplanes[j].normal, points[0]);
+ for (i = 1;i < 8;i++)
+ {
+ dist = DotProduct(r_shadow_rtlight_frustumplanes[j].normal, points[i]);
+ if (bestdist > dist)
+ bestdist = dist;
+ }
+ Con_Printf("light %p %splane #%i %f %f %f : %f < %f\n", rtlight, r_shadow_rtlight_frustumplanes[j].dist < bestdist + 0.03125 ? "^2" : "^1", j, r_shadow_rtlight_frustumplanes[j].normal[0], r_shadow_rtlight_frustumplanes[j].normal[1], r_shadow_rtlight_frustumplanes[j].normal[2], r_shadow_rtlight_frustumplanes[j].dist, bestdist);
+ // if the nearest point is near or behind the plane, we want this
+ // plane, otherwise the plane is useless as it won't cull anything
+ if (r_shadow_rtlight_frustumplanes[j].dist < bestdist + 0.03125)
+ {
+ PlaneClassify(&r_shadow_rtlight_frustumplanes[j]);
+ r_shadow_rtlight_frustumplanes[r_shadow_rtlight_numfrustumplanes++] = r_shadow_rtlight_frustumplanes[j];
+ }
+ }
+ }
+#endif
+}
+
+void R_Shadow_DrawWorldShadow(int numsurfaces, int *surfacelist, const unsigned char *trispvs)
+{
+ RSurf_ActiveWorldEntity();
+ if (r_shadow_rtlight->compiled && r_shadow_realtime_world_compile.integer && r_shadow_realtime_world_compileshadow.integer)
+ {
+ shadowmesh_t *mesh;
+ CHECKGLERROR
+ for (mesh = r_shadow_rtlight->static_meshchain_shadow;mesh;mesh = mesh->next)
+ {
+ r_refdef.stats.lights_shadowtriangles += mesh->numtriangles;
+ R_Mesh_VertexPointer(mesh->vertex3f, mesh->vbo, mesh->vbooffset_vertex3f);
+ GL_LockArrays(0, mesh->numverts);
+ if (r_shadow_rendermode == R_SHADOW_RENDERMODE_STENCIL)
+ {
+ // decrement stencil if backface is behind depthbuffer
+ GL_CullFace(GL_BACK); // quake is backwards, this culls front faces
+ qglStencilOp(GL_KEEP, GL_DECR, GL_KEEP);CHECKGLERROR
+ R_Mesh_Draw(0, mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->ebo, 0);
+ // increment stencil if frontface is behind depthbuffer
+ GL_CullFace(GL_FRONT); // quake is backwards, this culls back faces
+ qglStencilOp(GL_KEEP, GL_INCR, GL_KEEP);CHECKGLERROR
+ }
+ R_Mesh_Draw(0, mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->ebo, 0);
+ GL_LockArrays(0, 0);
+ }
+ CHECKGLERROR
+ }
+ else if (numsurfaces && r_refdef.worldmodel->brush.shadowmesh && r_shadow_culltriangles.integer)