+ R_FrameData_ReturnToMark();
+}
+
+void R_Q1BSP_CompileShadowMap(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativelightdirection, float lightradius, int numsurfaces, const int *surfacelist)
+{
+ dp_model_t *model = ent->model;
+ msurface_t *surface;
+ 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++)
+ {
+ surface = model->data_surfaces + surfacelist[surfacelistindex];
+ 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);
+}
+
+#define RSURF_MAX_BATCHSURFACES 8192
+
+static const msurface_t *batchsurfacelist[RSURF_MAX_BATCHSURFACES];
+
+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 unsigned char *surfacesides, const vec3_t lightmins, const vec3_t lightmaxs)
+{
+ dp_model_t *model = ent->model;
+ const msurface_t *surface;
+ int modelsurfacelistindex, batchnumsurfaces;
+ // check the box in modelspace, it was already checked in worldspace
+ if (!BoxesOverlap(model->normalmins, model->normalmaxs, lightmins, lightmaxs))
+ return;
+ R_FrameData_SetMark();
+ // identify lit faces within the bounding box
+ for (modelsurfacelistindex = 0;modelsurfacelistindex < modelnumsurfaces;modelsurfacelistindex++)
+ {
+ surface = model->data_surfaces + modelsurfacelist[modelsurfacelistindex];
+ if (surfacesides && !(surfacesides[modelsurfacelistindex] && (1 << side)))
+ continue;
+ rsurface.texture = R_GetCurrentTexture(surface->texture);
+ if (rsurface.texture->currentmaterialflags & MATERIALFLAG_NOSHADOW)
+ continue;
+ if (!BoxesOverlap(lightmins, lightmaxs, surface->mins, surface->maxs))
+ continue;
+ 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)
+ {
+ surface = model->data_surfaces + modelsurfacelist[modelsurfacelistindex];
+ if (surfacesides && !(surfacesides[modelsurfacelistindex] & (1 << side)))
+ continue;
+ if (surface->texture != batchsurfacelist[0]->texture)
+ break;
+ if (!BoxesOverlap(lightmins, lightmaxs, surface->mins, surface->maxs))
+ continue;
+ 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);
+ R_Mesh_PrepareVertices_Vertex3f(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
+ RSurf_DrawBatch();
+ }
+ R_FrameData_ReturnToMark();