+ // make this the active rtlight for rendering purposes
+ R_Shadow_RenderMode_ActiveLight(rtlight);
+
+ radiustolight = rtlight->matrix_worldtolight;
+ Matrix4x4_Abs(&radiustolight);
+
+ size = rtlight->shadowmapatlassidesize;
+ borderbias = r_shadow_shadowmapborder / (float)(size - r_shadow_shadowmapborder);
+
+ surfacesides = NULL;
+ castermask = 0;
+ receivermask = 0;
+ if (numsurfaces)
+ {
+ 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;
+ }
+ else
+ {
+ surfacesides = r_shadow_buffer_surfacesides;
+ for (i = 0; i < numsurfaces; i++)
+ {
+ msurface_t *surface = r_refdef.scene.worldmodel->data_surfaces + surfacelist[i];
+ surfacesides[i] = R_Shadow_CalcBBoxSideMask(surface->mins, surface->maxs, &rtlight->matrix_worldtolight, &radiustolight, borderbias);
+ castermask |= surfacesides[i];
+ receivermask |= surfacesides[i];
+ }
+ }
+ }
+
+ for (i = 0; i < numlightentities && receivermask < 0x3F; i++)
+ receivermask |= R_Shadow_CalcEntitySideMask(lightentities[i], &rtlight->matrix_worldtolight, &radiustolight, borderbias);
+ for (i = 0; i < numlightentities_noselfshadow && receivermask < 0x3F; i++)
+ receivermask |= R_Shadow_CalcEntitySideMask(lightentities_noselfshadow[i], &rtlight->matrix_worldtolight, &radiustolight, borderbias);
+
+ receivermask &= R_Shadow_CullFrustumSides(rtlight, size, r_shadow_shadowmapborder);
+
+ if (receivermask)
+ {
+ for (i = 0; i < numshadowentities; i++)
+ castermask |= (entitysides[i] = R_Shadow_CalcEntitySideMask(shadowentities[i], &rtlight->matrix_worldtolight, &radiustolight, borderbias));
+ for (i = 0; i < numshadowentities_noselfshadow; i++)
+ castermask |= (entitysides_noselfshadow[i] = R_Shadow_CalcEntitySideMask(shadowentities_noselfshadow[i], &rtlight->matrix_worldtolight, &radiustolight, borderbias));
+ }
+
+ // there is no need to render shadows for sides that have no receivers...
+ castermask &= receivermask;
+
+ //Con_Printf("distance %f lodlinear %i size %i\n", distance, lodlinear, size);
+
+ // render shadow casters into shadowmaps for this light
+ for (side = 0; side < 6; side++)
+ {
+ int bit = 1 << side;
+ if (castermask & bit)
+ {
+ R_Shadow_RenderMode_ShadowMap(side, size, rtlight->shadowmapatlasposition[0], rtlight->shadowmapatlasposition[1]);
+ if (numsurfaces)
+ R_Shadow_DrawWorldShadow_ShadowMap(numsurfaces, surfacelist, shadowtrispvs, surfacesides);
+ for (i = 0; i < numshadowentities; i++)
+ if (entitysides[i] & bit)
+ R_Shadow_DrawEntityShadow(shadowentities[i]);
+ for (i = 0; i < numshadowentities_noselfshadow; i++)
+ if (entitysides_noselfshadow[i] & bit)
+ R_Shadow_DrawEntityShadow(shadowentities_noselfshadow[i]);
+ }
+ }
+ // additionally if there are any noselfshadow casters we have to render a second set of shadowmaps without those :(
+ if (numshadowentities_noselfshadow)
+ {
+ for (side = 0; side < 6; side++)
+ {
+ int bit = 1 << side;
+ if (castermask & bit)
+ {
+ R_Shadow_RenderMode_ShadowMap(side, size, rtlight->shadowmapatlasposition[0] + size * 2, rtlight->shadowmapatlasposition[1]);
+ if (numsurfaces)
+ R_Shadow_DrawWorldShadow_ShadowMap(numsurfaces, surfacelist, shadowtrispvs, surfacesides);
+ for (i = 0; i < numshadowentities; i++)
+ if (entitysides[i] & bit)
+ R_Shadow_DrawEntityShadow(shadowentities[i]);
+ }
+ }
+ }
+}
+
+static void R_Shadow_DrawLight(rtlight_t *rtlight)
+{
+ int i;
+ int numsurfaces;
+ unsigned char *shadowtrispvs, *lighttrispvs;
+ int numlightentities;
+ int numlightentities_noselfshadow;
+ int numshadowentities;
+ int numshadowentities_noselfshadow;
+ entity_render_t **lightentities;
+ entity_render_t **lightentities_noselfshadow;
+ entity_render_t **shadowentities;
+ entity_render_t **shadowentities_noselfshadow;
+ int *surfacelist;
+ qboolean castshadows;
+
+ // check if we cached this light this frame (meaning it is worth drawing)
+ if (!rtlight->draw)
+ return;
+