]> de.git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
r_shadow_staticworldlights has mutated into r_shadow_realtime_world_compile, r_shadow...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 20 Apr 2005 05:33:29 +0000 (05:33 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 20 Apr 2005 05:33:29 +0000 (05:33 +0000)
added r_shadow_visiblelighting

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@5201 d7cf8633-e32d-0410-b094-e92efae38249

client.h
gl_models.c
gl_rmain.c
gl_rsurf.c
model_alias.c
model_brush.c
model_shared.h
r_shadow.c
r_shadow.h

index 93a35e1ce72ea829dcfa9702ea7f280aaa94963b..7dec18fff5411538cd62ede1c2a07a5edd6a7e03 100644 (file)
--- a/client.h
+++ b/client.h
@@ -145,6 +145,9 @@ typedef struct rtlight_s
        int static_numclusterpvsbytes;
        int *static_clusterlist;
        qbyte *static_clusterpvs;
+       // surfaces seen by light
+       int static_numsurfaces;
+       int *static_surfacelist;
 }
 rtlight_t;
 
index 5dfc5bc7a2dfba84889b7e5f13f6a35a2e044d65..c727b5f988c8c222dfcd4b2c1842fbd4a7a23fc1 100644 (file)
@@ -304,7 +304,7 @@ void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightor
        }
 }
 
-void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int numsurfaces, const int *surfacelist)
+void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int numsurfaces, const int *surfacelist, int visiblelighting)
 {
        int c, meshnum;
        float fog, ifog, lightcolorbase[3], lightcolorpants[3], lightcolorshirt[3];
@@ -386,7 +386,7 @@ void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v
                        Mod_BuildTextureVectorsAndNormals(0, mesh->num_vertices, mesh->num_triangles, vertex3f, mesh->data_texcoord2f, mesh->data_element3i, svector3f, tvector3f, normal3f);
                }
                c_alias_polys += mesh->num_triangles;
-               R_Shadow_RenderLighting(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i, vertex3f, svector3f, tvector3f, normal3f, mesh->data_texcoord2f, relativelightorigin, relativeeyeorigin, lightcolorbase, lightcolorpants, lightcolorshirt, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, (ent->colormap >= 0 || !texture->skin.merged) ? texture->skin.base : texture->skin.merged, ent->colormap >= 0 ? texture->skin.pants : 0, ent->colormap >= 0 ? texture->skin.shirt : 0, texture->skin.nmap, texture->skin.gloss, lightcubemap, ambientscale, diffusescale, specularscale);
+               R_Shadow_RenderLighting(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i, vertex3f, svector3f, tvector3f, normal3f, mesh->data_texcoord2f, relativelightorigin, relativeeyeorigin, lightcolorbase, lightcolorpants, lightcolorshirt, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, (ent->colormap >= 0 || !texture->skin.merged) ? texture->skin.base : texture->skin.merged, ent->colormap >= 0 ? texture->skin.pants : 0, ent->colormap >= 0 ? texture->skin.shirt : 0, texture->skin.nmap, texture->skin.gloss, lightcubemap, ambientscale, diffusescale, specularscale, visiblelighting);
        }
 }
 
index 6cac87e5e8dd6cdab416ad746a85ad8cc089e5e1..1d0bc1d2876cf27d7a75ee572198f40487e4617d 100644 (file)
@@ -930,7 +930,7 @@ void R_RenderScene(void)
                S_ExtraUpdate ();
 
        GL_ShowTrisColor(0, 0, 0.033, 1);
-       R_ShadowVolumeLighting(false);
+       R_ShadowVolumeLighting(false, false);
        R_TimeReport("rtlights");
 
        // don't let sound skip if going slow
@@ -960,9 +960,9 @@ void R_RenderScene(void)
        R_MeshQueue_Render();
        R_MeshQueue_EndScene();
 
-       if (r_shadow_visiblevolumes.integer && !r_showtrispass)
+       if ((r_shadow_visiblelighting.integer || r_shadow_visiblevolumes.integer) && !r_showtrispass)
        {
-               R_ShadowVolumeLighting(true);
+               R_ShadowVolumeLighting(r_shadow_visiblelighting.integer, r_shadow_visiblevolumes.integer);
                R_TimeReport("shadowvolume");
        }
 
index 1cb5146d43b9532f932ddbf8a368a0f3deed6d60..fcfdf8c702ecd2c646bb1b7c3d94cb910dcacef9 100644 (file)
@@ -1858,7 +1858,7 @@ void R_Q1BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin,
        }
 }
 
-void R_Q1BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int numsurfaces, const int *surfacelist)
+void R_Q1BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int numsurfaces, const int *surfacelist, int visiblelighting)
 {
        model_t *model = ent->model;
        msurface_t *surface;
@@ -1889,7 +1889,7 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t
                                {
                                        if (surface->texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
                                                qglDisable(GL_CULL_FACE);
-                                       R_Shadow_RenderLighting(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle), surface->groupmesh->data_vertex3f, surface->groupmesh->data_svector3f, surface->groupmesh->data_tvector3f, surface->groupmesh->data_normal3f, surface->groupmesh->data_texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightcolor, NULL, NULL, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, NULL, NULL, t->skin.nmap, t->skin.gloss, lightcubemap, ambientscale, diffusescale, specularscale);
+                                       R_Shadow_RenderLighting(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle), surface->groupmesh->data_vertex3f, surface->groupmesh->data_svector3f, surface->groupmesh->data_tvector3f, surface->groupmesh->data_normal3f, surface->groupmesh->data_texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightcolor, NULL, NULL, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, NULL, NULL, t->skin.nmap, t->skin.gloss, lightcubemap, ambientscale, diffusescale, specularscale, visiblelighting);
                                        if (surface->texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
                                                qglEnable(GL_CULL_FACE);
                                }
index fcaa747c198c23c572a41fc0ff86516ba5b5a851..1549bc3d2baf50f3f5599e5a7ad0f4d942741f12 100644 (file)
@@ -414,7 +414,7 @@ static void Mod_BuildAliasSkinsFromSkinFiles(texture_t *skin, skinfile_t *skinfi
 #define BOUNDF(VALUE,MIN,MAX) if (VALUE < MIN || VALUE >= MAX) Host_Error("model %s has an invalid ##VALUE (%f exceeds %f - %f)\n", loadmodel->name, VALUE, MIN, MAX);
 extern void R_Model_Alias_Draw(entity_render_t *ent);
 extern void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int numsurfaces, const int *surfacelist, const vec3_t lightmins, const vec3_t lightmaxs);
-extern void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int numsurfaces, const int *surfacelist);
+extern void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int numsurfaces, const int *surfacelist, int visiblelighting);
 void Mod_IDP0_Load(model_t *mod, void *buffer)
 {
        int i, j, version, totalskins, skinwidth, skinheight, groupframes, groupskins, numverts;
index 71fb4990abd9a04ac49592971528bff2b37491ad..20856b6e50cd11d8c6d8bd84889f78cd35fbee17 100644 (file)
@@ -2874,7 +2874,7 @@ extern void R_Q1BSP_DrawSky(entity_render_t *ent);
 extern void R_Q1BSP_Draw(entity_render_t *ent);
 extern void R_Q1BSP_GetLightInfo(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, vec3_t outmins, vec3_t outmaxs, int *outclusterlist, qbyte *outclusterpvs, int *outnumclusterspointer, int *outsurfacelist, qbyte *outsurfacepvs, int *outnumsurfacespointer);
 extern void R_Q1BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int numsurfaces, const int *surfacelist, const vec3_t lightmins, const vec3_t lightmaxs);
-extern void R_Q1BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int numsurfaces, const int *surfacelist);
+extern void R_Q1BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int numsurfaces, const int *surfacelist, int visiblelighting);
 void Mod_Q1BSP_Load(model_t *mod, void *buffer)
 {
        int i, j, k;
index 9456dabf0db7012f1a6a4c9aa05887bfec3dffda..349a9619439651fa9139974a88fe15b25eed4c7e 100644 (file)
@@ -406,7 +406,7 @@ typedef struct model_s
        // draw a shadow volume for the model based on light source
        void(*DrawShadowVolume)(struct entity_render_s *ent, vec3_t relativelightorigin, float lightradius, int numsurfaces, const int *surfacelist, const vec3_t lightmins, const vec3_t lightmaxs);
        // draw the lighting on a model (through stencil)
-       void(*DrawLight)(struct entity_render_s *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int numsurfaces, const int *surfacelist);
+       void(*DrawLight)(struct entity_render_s *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int numsurfaces, const int *surfacelist, int visiblelighting);
        // trace a box against this model
        void (*TraceBox)(struct model_s *model, int frame, struct trace_s *trace, const vec3_t boxstartmins, const vec3_t boxstartmaxs, const vec3_t boxendmins, const vec3_t boxendmaxs, int hitsupercontentsmask);
        // fields belonging to each type of model
index f74c32e98b81857ef78ba7a2c8d7139168bd6797..ad59941dbafb03bcd003e8394ead0e74ab4b72ec 100644 (file)
@@ -180,12 +180,15 @@ cvar_t r_shadow_realtime_world = {CVAR_SAVE, "r_shadow_realtime_world", "0"};
 cvar_t r_shadow_realtime_world_dlightshadows = {CVAR_SAVE, "r_shadow_realtime_world_dlightshadows", "1"};
 cvar_t r_shadow_realtime_world_lightmaps = {CVAR_SAVE, "r_shadow_realtime_world_lightmaps", "0"};
 cvar_t r_shadow_realtime_world_shadows = {CVAR_SAVE, "r_shadow_realtime_world_shadows", "1"};
+cvar_t r_shadow_realtime_world_compile = {0, "r_shadow_realtime_world_compile", "1"};
+cvar_t r_shadow_realtime_world_compilelight = {0, "r_shadow_realtime_world_compilelight", "1"};
+cvar_t r_shadow_realtime_world_compileshadow = {0, "r_shadow_realtime_world_compileshadow", "1"};
 cvar_t r_shadow_scissor = {0, "r_shadow_scissor", "1"};
 cvar_t r_shadow_shadow_polygonfactor = {0, "r_shadow_shadow_polygonfactor", "0"};
 cvar_t r_shadow_shadow_polygonoffset = {0, "r_shadow_shadow_polygonoffset", "1"};
 cvar_t r_shadow_singlepassvolumegeneration = {0, "r_shadow_singlepassvolumegeneration", "1"};
-cvar_t r_shadow_staticworldlights = {0, "r_shadow_staticworldlights", "1"};
 cvar_t r_shadow_texture3d = {0, "r_shadow_texture3d", "1"};
+cvar_t r_shadow_visiblelighting = {0, "r_shadow_visiblelighting", "0"};
 cvar_t r_shadow_visiblevolumes = {0, "r_shadow_visiblevolumes", "0"};
 cvar_t r_shadow_glsl = {0, "r_shadow_glsl", "1"};
 cvar_t r_shadow_glsl_offsetmapping = {0, "r_shadow_glsl_offsetmapping", "1"};
@@ -561,6 +564,9 @@ void R_Shadow_Help_f(void)
 "r_shadow_realtime_world_dlightshadows : cast shadows from dlights\n"
 "r_shadow_realtime_world_lightmaps : use lightmaps in addition to lights\n"
 "r_shadow_realtime_world_shadows : cast shadows from world lights\n"
+"r_shadow_realtime_world_compile : compile surface/visibility information\n"
+"r_shadow_realtime_world_compilelight : compile lighting geometry\n"
+"r_shadow_realtime_world_compileshadow : compile shadow geometry\n"
 "r_shadow_glsl : use OpenGL Shading Language for lighting\n"
 "r_shadow_glsl_offsetmapping : enables Offset Mapping bumpmap enhancement\n"
 "r_shadow_glsl_offsetmapping_scale : controls depth of Offset Mapping\n"
@@ -570,6 +576,7 @@ void R_Shadow_Help_f(void)
 "r_shadow_shadow_polygonoffset : nudge shadow volumes closer/further\n"
 "r_shadow_singlepassvolumegeneration : selects shadow volume algorithm\n"
 "r_shadow_texture3d : use 3d attenuation texture (if hardware supports)\n"
+"r_shadow_visiblelighting : useful for performance testing; bright = slow!\n"
 "r_shadow_visiblevolumes : useful for performance testing; bright = slow!\n"
 "Commands:\n"
 "r_shadow_help : this help\n"
@@ -596,12 +603,15 @@ void R_Shadow_Init(void)
        Cvar_RegisterVariable(&r_shadow_realtime_world_dlightshadows);
        Cvar_RegisterVariable(&r_shadow_realtime_world_lightmaps);
        Cvar_RegisterVariable(&r_shadow_realtime_world_shadows);
+       Cvar_RegisterVariable(&r_shadow_realtime_world_compile);
+       Cvar_RegisterVariable(&r_shadow_realtime_world_compilelight);
+       Cvar_RegisterVariable(&r_shadow_realtime_world_compileshadow);
        Cvar_RegisterVariable(&r_shadow_scissor);
        Cvar_RegisterVariable(&r_shadow_shadow_polygonfactor);
        Cvar_RegisterVariable(&r_shadow_shadow_polygonoffset);
        Cvar_RegisterVariable(&r_shadow_singlepassvolumegeneration);
-       Cvar_RegisterVariable(&r_shadow_staticworldlights);
        Cvar_RegisterVariable(&r_shadow_texture3d);
+       Cvar_RegisterVariable(&r_shadow_visiblelighting);
        Cvar_RegisterVariable(&r_shadow_visiblevolumes);
        Cvar_RegisterVariable(&r_shadow_glsl);
        Cvar_RegisterVariable(&r_shadow_glsl_offsetmapping);
@@ -1548,7 +1558,7 @@ static void R_Shadow_GenTexCoords_Specular_NormalCubeMap(float *out3f, int numve
        }
 }
 
-void R_Shadow_RenderLighting(int firstvertex, int numvertices, int numtriangles, const int *elements, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const float *texcoord2f, const float *relativelightorigin, const float *relativeeyeorigin, const float *lightcolorbase, const float *lightcolorpants, const float *lightcolorshirt, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *bumptexture, rtexture_t *glosstexture, rtexture_t *lightcubemap, vec_t ambientscale, vec_t diffusescale, vec_t specularscale)
+void R_Shadow_RenderLighting(int firstvertex, int numvertices, int numtriangles, const int *elements, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const float *texcoord2f, const float *relativelightorigin, const float *relativeeyeorigin, const float *lightcolorbase, const float *lightcolorpants, const float *lightcolorshirt, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *bumptexture, rtexture_t *glosstexture, rtexture_t *lightcubemap, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int visiblelighting)
 {
        int renders;
        float color[3], color2[3], colorscale;
@@ -1583,6 +1593,124 @@ void R_Shadow_RenderLighting(int firstvertex, int numvertices, int numtriangles,
                lightcubemap = r_shadow_blankwhitecubetexture;
        if ((ambientscale + diffusescale) * (VectorLength2(lightcolorbase) + VectorLength2(lightcolorpants) + VectorLength2(lightcolorshirt)) + specularscale * VectorLength2(lightcolorbase) <= 0.001)
                return;
+       if (visiblelighting)
+       {
+               int passes = 0;
+               if (r_shadow_glsl.integer && r_shadow_program_light[0])
+                       passes++; // GLSL shader path (GFFX5200, Radeon 9500)
+               else if (gl_dot3arb && gl_texturecubemap && gl_combine.integer && gl_stencil)
+               {
+                       // TODO: add direct pants/shirt rendering
+                       if (pantstexture && (ambientscale + diffusescale) * VectorLength2(lightcolorpants) > 0.001)
+                               R_Shadow_RenderLighting(firstvertex, numvertices, numtriangles, elements, vertex3f, svector3f, tvector3f, normal3f, texcoord2f, relativelightorigin, relativeeyeorigin, lightcolorpants, NULL, NULL, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, pantstexture, NULL, NULL, bumptexture, NULL, lightcubemap, ambientscale, diffusescale, specularscale, visiblelighting);
+                       if (shirttexture && (ambientscale + diffusescale) * VectorLength2(lightcolorshirt) > 0.001)
+                               R_Shadow_RenderLighting(firstvertex, numvertices, numtriangles, elements, vertex3f, svector3f, tvector3f, normal3f, texcoord2f, relativelightorigin, relativeeyeorigin, lightcolorshirt, NULL, NULL, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, shirttexture, NULL, NULL, bumptexture, NULL, lightcubemap, ambientscale, diffusescale, specularscale, visiblelighting);
+                       if (!bumptexture)
+                               bumptexture = r_texture_blanknormalmap;
+                       if (!glosstexture)
+                               glosstexture = r_texture_white;
+                       if (ambientscale)
+                       {
+                               colorscale = ambientscale;
+                               if (r_shadow_texture3d.integer && lightcubemap && r_textureunits.integer >= 4)
+                               {
+                               }
+                               else if (r_shadow_texture3d.integer && !lightcubemap && r_textureunits.integer >= 2)
+                               {
+                               }
+                               else if (r_textureunits.integer >= 4 && lightcubemap)
+                               {
+                               }
+                               else if (r_textureunits.integer >= 3 && !lightcubemap)
+                               {
+                               }
+                               else
+                                       passes++;
+                               VectorScale(lightcolorbase, colorscale, color2);
+                               for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
+                                       passes++;
+                       }
+                       if (diffusescale)
+                       {
+                               colorscale = diffusescale;
+                               if (r_shadow_texture3d.integer && r_textureunits.integer >= 4)
+                               {
+                                       // 3/2 3D combine path (Geforce3, Radeon 8500)
+                                       passes++;
+                               }
+                               else if (r_shadow_texture3d.integer && r_textureunits.integer >= 2 && lightcubemap)
+                               {
+                                       // 1/2/2 3D combine path (original Radeon)
+                                       passes += 2;
+                               }
+                               else if (r_shadow_texture3d.integer && r_textureunits.integer >= 2 && !lightcubemap)
+                               {
+                                       // 2/2 3D combine path (original Radeon)
+                                       passes++;
+                               }
+                               else if (r_textureunits.integer >= 4)
+                               {
+                                       // 4/2 2D combine path (Geforce3, Radeon 8500)
+                                       passes++;
+                               }
+                               else
+                               {
+                                       // 2/2/2 2D combine path (any dot3 card)
+                                       passes += 2;
+                               }
+                               VectorScale(lightcolorbase, colorscale, color2);
+                               for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
+                                       passes++;
+                       }
+                       if (specularscale && glosstexture != r_texture_black)
+                       {
+                               //if (gl_support_blendsquare)
+                               {
+                                       colorscale = specularscale;
+                                       if (r_shadow_texture3d.integer && r_textureunits.integer >= 2 && lightcubemap /*&& gl_support_blendsquare*/) // FIXME: detect blendsquare!
+                                               passes += 4;
+                                       else if (r_shadow_texture3d.integer && r_textureunits.integer >= 2 && !lightcubemap /*&& gl_support_blendsquare*/) // FIXME: detect blendsquare!
+                                               passes += 3;
+                                       else
+                                               passes += 4;
+                                       VectorScale(lightcolorbase, colorscale, color2);
+                                       for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
+                                               passes++;
+                               }
+                       }
+               }
+               else
+               {
+                       // TODO: add direct pants/shirt rendering
+                       if (pantstexture && (ambientscale + diffusescale) * VectorLength2(lightcolorpants) > 0.001)
+                               R_Shadow_RenderLighting(firstvertex, numvertices, numtriangles, elements, vertex3f, svector3f, tvector3f, normal3f, texcoord2f, relativelightorigin, relativeeyeorigin, lightcolorpants, NULL, NULL, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, pantstexture, NULL, NULL, bumptexture, NULL, lightcubemap, ambientscale, diffusescale, specularscale, visiblelighting);
+                       if (shirttexture && (ambientscale + diffusescale) * VectorLength2(lightcolorshirt) > 0.001)
+                               R_Shadow_RenderLighting(firstvertex, numvertices, numtriangles, elements, vertex3f, svector3f, tvector3f, normal3f, texcoord2f, relativelightorigin, relativeeyeorigin, lightcolorshirt, NULL, NULL, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, shirttexture, NULL, NULL, bumptexture, NULL, lightcubemap, ambientscale, diffusescale, specularscale, visiblelighting);
+                       if (ambientscale)
+                       {
+                               VectorScale(lightcolorbase, ambientscale, color2);
+                               for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
+                                       passes++;
+                       }
+                       if (diffusescale)
+                       {
+                               VectorScale(lightcolorbase, diffusescale, color2);
+                               for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
+                                       passes++;
+                       }
+               }
+               if (passes)
+               {
+                       GL_Color(0.1*passes, 0.025*passes, 0, 1);
+                       memset(&m, 0, sizeof(m));
+                       m.pointer_vertex = vertex3f;
+                       R_Mesh_State(&m);
+                       GL_LockArrays(firstvertex, numvertices);
+                       R_Mesh_Draw(firstvertex, numvertices, numtriangles, elements);
+                       GL_LockArrays(0, 0);
+               }
+               return;
+       }
        // FIXME: support EF_NODEPTHTEST
        GL_DepthMask(false);
        GL_DepthTest(true);
@@ -1677,9 +1805,9 @@ void R_Shadow_RenderLighting(int firstvertex, int numvertices, int numtriangles,
        {
                // TODO: add direct pants/shirt rendering
                if (pantstexture && (ambientscale + diffusescale) * VectorLength2(lightcolorpants) > 0.001)
-                       R_Shadow_RenderLighting(firstvertex, numvertices, numtriangles, elements, vertex3f, svector3f, tvector3f, normal3f, texcoord2f, relativelightorigin, relativeeyeorigin, lightcolorpants, NULL, NULL, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, pantstexture, NULL, NULL, bumptexture, NULL, lightcubemap, ambientscale, diffusescale, specularscale);
+                       R_Shadow_RenderLighting(firstvertex, numvertices, numtriangles, elements, vertex3f, svector3f, tvector3f, normal3f, texcoord2f, relativelightorigin, relativeeyeorigin, lightcolorpants, NULL, NULL, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, pantstexture, NULL, NULL, bumptexture, NULL, lightcubemap, ambientscale, diffusescale, specularscale, visiblelighting);
                if (shirttexture && (ambientscale + diffusescale) * VectorLength2(lightcolorshirt) > 0.001)
-                       R_Shadow_RenderLighting(firstvertex, numvertices, numtriangles, elements, vertex3f, svector3f, tvector3f, normal3f, texcoord2f, relativelightorigin, relativeeyeorigin, lightcolorshirt, NULL, NULL, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, shirttexture, NULL, NULL, bumptexture, NULL, lightcubemap, ambientscale, diffusescale, specularscale);
+                       R_Shadow_RenderLighting(firstvertex, numvertices, numtriangles, elements, vertex3f, svector3f, tvector3f, normal3f, texcoord2f, relativelightorigin, relativeeyeorigin, lightcolorshirt, NULL, NULL, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, shirttexture, NULL, NULL, bumptexture, NULL, lightcubemap, ambientscale, diffusescale, specularscale, visiblelighting);
                if (!bumptexture)
                        bumptexture = r_texture_blanknormalmap;
                if (!glosstexture)
@@ -2374,9 +2502,9 @@ void R_Shadow_RenderLighting(int firstvertex, int numvertices, int numtriangles,
        {
                // TODO: add direct pants/shirt rendering
                if (pantstexture && (ambientscale + diffusescale) * VectorLength2(lightcolorpants) > 0.001)
-                       R_Shadow_RenderLighting(firstvertex, numvertices, numtriangles, elements, vertex3f, svector3f, tvector3f, normal3f, texcoord2f, relativelightorigin, relativeeyeorigin, lightcolorpants, NULL, NULL, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, pantstexture, NULL, NULL, bumptexture, NULL, lightcubemap, ambientscale, diffusescale, specularscale);
+                       R_Shadow_RenderLighting(firstvertex, numvertices, numtriangles, elements, vertex3f, svector3f, tvector3f, normal3f, texcoord2f, relativelightorigin, relativeeyeorigin, lightcolorpants, NULL, NULL, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, pantstexture, NULL, NULL, bumptexture, NULL, lightcubemap, ambientscale, diffusescale, specularscale, visiblelighting);
                if (shirttexture && (ambientscale + diffusescale) * VectorLength2(lightcolorshirt) > 0.001)
-                       R_Shadow_RenderLighting(firstvertex, numvertices, numtriangles, elements, vertex3f, svector3f, tvector3f, normal3f, texcoord2f, relativelightorigin, relativeeyeorigin, lightcolorshirt, NULL, NULL, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, shirttexture, NULL, NULL, bumptexture, NULL, lightcubemap, ambientscale, diffusescale, specularscale);
+                       R_Shadow_RenderLighting(firstvertex, numvertices, numtriangles, elements, vertex3f, svector3f, tvector3f, normal3f, texcoord2f, relativelightorigin, relativeeyeorigin, lightcolorshirt, NULL, NULL, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, shirttexture, NULL, NULL, bumptexture, NULL, lightcubemap, ambientscale, diffusescale, specularscale, visiblelighting);
                if (ambientscale)
                {
                        GL_BlendFunc(GL_ONE, GL_ONE);
@@ -2539,9 +2667,10 @@ void R_RTLight_UpdateFromDLight(rtlight_t *rtlight, const dlight_t *light, int i
 // (undone by R_FreeCompiledRTLight, which R_UpdateLight calls)
 void R_RTLight_Compile(rtlight_t *rtlight)
 {
-       int shadowmeshes, shadowtris, lightmeshes, lighttris, numclusters, numsurfaces;
+       int shadowmeshes, shadowtris, lightmeshes, lighttris, numclusters, numclusterpvsbytes, numsurfaces;
        entity_render_t *ent = r_refdef.worldentity;
        model_t *model = r_refdef.worldmodel;
+       qbyte *data;
 
        // compile the light
        rtlight->compiled = true;
@@ -2549,6 +2678,8 @@ void R_RTLight_Compile(rtlight_t *rtlight)
        rtlight->static_numclusterpvsbytes = 0;
        rtlight->static_clusterlist = NULL;
        rtlight->static_clusterpvs = NULL;
+       rtlight->static_numsurfaces = 0;
+       rtlight->static_surfacelist = NULL;
        rtlight->cullmins[0] = rtlight->shadoworigin[0] - rtlight->radius;
        rtlight->cullmins[1] = rtlight->shadoworigin[1] - rtlight->radius;
        rtlight->cullmins[2] = rtlight->shadoworigin[2] - rtlight->radius;
@@ -2562,15 +2693,20 @@ void R_RTLight_Compile(rtlight_t *rtlight)
                r_shadow_compilingrtlight = rtlight;
                R_Shadow_EnlargeClusterSurfaceBuffer(model->brush.num_pvsclusters, model->nummodelsurfaces);
                model->GetLightInfo(ent, rtlight->shadoworigin, rtlight->radius, rtlight->cullmins, rtlight->cullmaxs, r_shadow_buffer_clusterlist, r_shadow_buffer_clusterpvs, &numclusters, r_shadow_buffer_surfacelist, r_shadow_buffer_surfacepvs, &numsurfaces);
-               rtlight->static_numclusterpvsbytes = (model->brush.num_pvsclusters + 7) >> 3;
-               rtlight->static_clusterpvs = Mem_Alloc(r_shadow_mempool, rtlight->static_numclusterpvsbytes);
+               numclusterpvsbytes = (model->brush.num_pvsclusters + 7) >> 3;
+               data = Mem_Alloc(r_shadow_mempool, sizeof(int) * numclusters + numclusterpvsbytes + sizeof(int) * numsurfaces);
+               rtlight->static_numclusters = numclusters;
+               rtlight->static_numclusterpvsbytes = numclusterpvsbytes;
+               rtlight->static_clusterlist = (void *)data;data += sizeof(int) * numclusters;
+               rtlight->static_clusterpvs = (void *)data;data += numclusterpvsbytes;
+               rtlight->static_numsurfaces = numsurfaces;
+               rtlight->static_surfacelist = (void *)data;data += sizeof(int) * numsurfaces;
                if (numclusters)
-               {
-                       rtlight->static_numclusters = numclusters;
-                       rtlight->static_clusterlist = Mem_Alloc(r_shadow_mempool, rtlight->static_numclusters * sizeof(*rtlight->static_clusterlist));
                        memcpy(rtlight->static_clusterlist, r_shadow_buffer_clusterlist, rtlight->static_numclusters * sizeof(*rtlight->static_clusterlist));
+               if (numclusterpvsbytes)
                        memcpy(rtlight->static_clusterpvs, r_shadow_buffer_clusterpvs, rtlight->static_numclusterpvsbytes);
-               }
+               if (numsurfaces)
+                       memcpy(rtlight->static_surfacelist, r_shadow_buffer_surfacelist, rtlight->static_numsurfaces * sizeof(*rtlight->static_surfacelist));
                if (model->DrawShadowVolume && rtlight->shadow)
                {
                        rtlight->static_meshchain_shadow = Mod_ShadowMesh_Begin(r_shadow_mempool, 32768, 32768, NULL, NULL, NULL, false, false, true);
@@ -2580,7 +2716,7 @@ void R_RTLight_Compile(rtlight_t *rtlight)
                if (model->DrawLight)
                {
                        rtlight->static_meshchain_light = Mod_ShadowMesh_Begin(r_shadow_mempool, 32768, 32768, NULL, NULL, NULL, true, false, true);
-                       model->DrawLight(ent, rtlight->shadoworigin, vec3_origin, rtlight->radius, vec3_origin, &r_identitymatrix, &r_identitymatrix, &r_identitymatrix, NULL, 0, 0, 0, numsurfaces, r_shadow_buffer_surfacelist);
+                       model->DrawLight(ent, rtlight->shadoworigin, vec3_origin, rtlight->radius, vec3_origin, &r_identitymatrix, &r_identitymatrix, &r_identitymatrix, NULL, 0, 0, 0, numsurfaces, r_shadow_buffer_surfacelist, 0);
                        rtlight->static_meshchain_light = Mod_ShadowMesh_Finish(r_shadow_mempool, rtlight->static_meshchain_light, true, false);
                }
                // switch back to rendering when DrawShadowVolume or DrawLight is called
@@ -2629,14 +2765,15 @@ void R_RTLight_Uncompile(rtlight_t *rtlight)
                if (rtlight->static_meshchain_light)
                        Mod_ShadowMesh_Free(rtlight->static_meshchain_light);
                rtlight->static_meshchain_light = NULL;
+               // these allocations are grouped
                if (rtlight->static_clusterlist)
                        Mem_Free(rtlight->static_clusterlist);
-               rtlight->static_clusterlist = NULL;
-               if (rtlight->static_clusterpvs)
-                       Mem_Free(rtlight->static_clusterpvs);
-               rtlight->static_clusterpvs = NULL;
                rtlight->static_numclusters = 0;
                rtlight->static_numclusterpvsbytes = 0;
+               rtlight->static_clusterlist = NULL;
+               rtlight->static_clusterpvs = NULL;
+               rtlight->static_numsurfaces = 0;
+               rtlight->static_surfacelist = NULL;
                rtlight->compiled = false;
        }
 }
@@ -2648,7 +2785,7 @@ void R_Shadow_UncompileWorldLights(void)
                R_RTLight_Uncompile(&light->rtlight);
 }
 
-void R_DrawRTLight(rtlight_t *rtlight, int visiblevolumes)
+void R_DrawRTLight(rtlight_t *rtlight, int visiblelighting, int visiblevolumes)
 {
        int i, shadow, usestencil;
        entity_render_t *ent;
@@ -2682,7 +2819,7 @@ void R_DrawRTLight(rtlight_t *rtlight, int visiblevolumes)
        // loading is done before visibility checks because loading should happen
        // all at once at the start of a level, not when it stalls gameplay.
        // (especially important to benchmarks)
-       if (rtlight->isstatic && !rtlight->compiled && r_shadow_staticworldlights.integer)
+       if (rtlight->isstatic && !rtlight->compiled && r_shadow_realtime_world_compile.integer)
                R_RTLight_Compile(rtlight);
        if (rtlight->cubemapname[0])
                cubemaptexture = R_Shadow_Cubemap(rtlight->cubemapname);
@@ -2702,13 +2839,15 @@ void R_DrawRTLight(rtlight_t *rtlight, int visiblevolumes)
        clusterpvs = NULL;
        numsurfaces = 0;
        surfacelist = NULL;
-       if (rtlight->compiled && r_shadow_staticworldlights.integer)
+       if (rtlight->compiled && r_shadow_realtime_world_compile.integer)
        {
                // compiled light, world available and can receive realtime lighting
                // retrieve cluster information
                numclusters = rtlight->static_numclusters;
                clusterlist = rtlight->static_clusterlist;
                clusterpvs = rtlight->static_clusterpvs;
+               numsurfaces = rtlight->static_numsurfaces;
+               surfacelist = rtlight->static_surfacelist;
                VectorCopy(rtlight->cullmins, cullmins);
                VectorCopy(rtlight->cullmaxs, cullmaxs);
        }
@@ -2744,15 +2883,21 @@ void R_DrawRTLight(rtlight_t *rtlight, int visiblevolumes)
        shadow = rtlight->shadow && (rtlight->isstatic ? r_rtworldshadows : r_rtdlightshadows);
        usestencil = false;
 
-       if (shadow && (gl_stencil || visiblevolumes))
+       if (shadow && ((gl_stencil && !visiblelighting) || visiblevolumes))
        {
-               if (!visiblevolumes)
+               if (visiblevolumes)
+               {
+                       qglDisable(GL_CULL_FACE);
+                       GL_DepthTest(visiblevolumes < 2);
+                       GL_Color(0.0, 0.0125, 0.1, 1);
+               }
+               else
                {
                        R_Shadow_Stage_ShadowVolumes();
                        usestencil = true;
                }
                ent = r_refdef.worldentity;
-               if (r_shadow_staticworldlights.integer && rtlight->compiled)
+               if (rtlight->compiled && r_shadow_realtime_world_compile.integer && r_shadow_realtime_world_compileshadow.integer)
                {
                        memset(&m, 0, sizeof(m));
                        R_Mesh_Matrix(&ent->matrix);
@@ -2814,9 +2959,16 @@ void R_DrawRTLight(rtlight_t *rtlight, int visiblevolumes)
                }
        }
 
-       if (!visiblevolumes)
+       if (visiblelighting || !visiblevolumes)
        {
-               R_Shadow_Stage_Light(usestencil);
+               if (visiblelighting)
+               {
+                       qglEnable(GL_CULL_FACE);
+                       GL_DepthTest(visiblelighting < 2);
+                       GL_Color(0.1, 0.0125, 0, 1);
+               }
+               else
+                       R_Shadow_Stage_Light(usestencil);
 
                ent = r_refdef.worldentity;
                if (ent->model && ent->model->DrawLight && (ent->flags & RENDER_LIGHT))
@@ -2829,14 +2981,14 @@ void R_DrawRTLight(rtlight_t *rtlight, int visiblevolumes)
                        Matrix4x4_Concat(&matrix_modeltolight, &rtlight->matrix_worldtolight, &ent->matrix);
                        Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &rtlight->matrix_worldtoattenuationxyz, &ent->matrix);
                        Matrix4x4_Concat(&matrix_modeltoattenuationz, &rtlight->matrix_worldtoattenuationz, &ent->matrix);
-                       if (r_shadow_staticworldlights.integer && rtlight->compiled)
+                       if (rtlight->compiled && r_shadow_realtime_world_compile.integer && r_shadow_realtime_world_compilelight.integer)
                        {
                                R_Mesh_Matrix(&ent->matrix);
                                for (mesh = rtlight->static_meshchain_light;mesh;mesh = mesh->next)
-                                       R_Shadow_RenderLighting(0, mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoord2f, relativelightorigin, relativeeyeorigin, lightcolor2, NULL, NULL, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, mesh->map_diffuse, NULL, NULL, mesh->map_normal, mesh->map_specular, cubemaptexture, rtlight->ambientscale, rtlight->diffusescale, rtlight->specularscale);
+                                       R_Shadow_RenderLighting(0, mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoord2f, relativelightorigin, relativeeyeorigin, lightcolor2, NULL, NULL, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, mesh->map_diffuse, NULL, NULL, mesh->map_normal, mesh->map_specular, cubemaptexture, rtlight->ambientscale, rtlight->diffusescale, rtlight->specularscale, visiblelighting);
                        }
                        else
-                               ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, rtlight->radius, lightcolor2, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, cubemaptexture, rtlight->ambientscale, rtlight->diffusescale, rtlight->specularscale, numsurfaces, surfacelist);
+                               ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, rtlight->radius, lightcolor2, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, cubemaptexture, rtlight->ambientscale, rtlight->diffusescale, rtlight->specularscale, numsurfaces, surfacelist, visiblelighting);
                }
                if (r_drawentities.integer)
                {
@@ -2855,14 +3007,14 @@ void R_DrawRTLight(rtlight_t *rtlight, int visiblevolumes)
                                        Matrix4x4_Concat(&matrix_modeltolight, &rtlight->matrix_worldtolight, &ent->matrix);
                                        Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &rtlight->matrix_worldtoattenuationxyz, &ent->matrix);
                                        Matrix4x4_Concat(&matrix_modeltoattenuationz, &rtlight->matrix_worldtoattenuationz, &ent->matrix);
-                                       ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, rtlight->radius, lightcolor2, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, cubemaptexture, rtlight->ambientscale, rtlight->diffusescale, rtlight->specularscale, ent->model->nummodelsurfaces, ent->model->surfacelist);
+                                       ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, rtlight->radius, lightcolor2, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, cubemaptexture, rtlight->ambientscale, rtlight->diffusescale, rtlight->specularscale, ent->model->nummodelsurfaces, ent->model->surfacelist, visiblelighting);
                                }
                        }
                }
        }
 }
 
-void R_ShadowVolumeLighting(int visiblevolumes)
+void R_ShadowVolumeLighting(int visiblelighting, int visiblevolumes)
 {
        int lnum, flag;
        dlight_t *light;
@@ -2871,16 +3023,14 @@ void R_ShadowVolumeLighting(int visiblevolumes)
        if (r_refdef.worldmodel && strncmp(r_refdef.worldmodel->name, r_shadow_mapname, sizeof(r_shadow_mapname)))
                R_Shadow_EditLights_Reload_f();
 
-       if (visiblevolumes)
+       if (visiblelighting || visiblevolumes)
        {
                memset(&m, 0, sizeof(m));
                R_Mesh_State(&m);
 
                GL_BlendFunc(GL_ONE, GL_ONE);
                GL_DepthMask(false);
-               GL_DepthTest(r_shadow_visiblevolumes.integer < 2);
-               qglDisable(GL_CULL_FACE);
-               GL_Color(0.0, 0.0125, 0.1, 1);
+               qglCullFace(GL_FRONT); // this culls back
        }
        else
                R_Shadow_Stage_Begin();
@@ -2889,17 +3039,17 @@ void R_ShadowVolumeLighting(int visiblevolumes)
        {
                for (lnum = 0, light = r_shadow_worldlightchain;light;lnum++, light = light->next)
                        if (lnum == r_shadow_debuglight.integer && (light->flags & flag))
-                               R_DrawRTLight(&light->rtlight, visiblevolumes);
+                               R_DrawRTLight(&light->rtlight, visiblelighting, visiblevolumes);
        }
        else
                for (lnum = 0, light = r_shadow_worldlightchain;light;lnum++, light = light->next)
                        if (light->flags & flag)
-                               R_DrawRTLight(&light->rtlight, visiblevolumes);
+                               R_DrawRTLight(&light->rtlight, visiblelighting, visiblevolumes);
        if (r_rtdlight)
                for (lnum = 0, light = r_dlight;lnum < r_numdlights;lnum++, light++)
-                       R_DrawRTLight(&light->rtlight, visiblevolumes);
+                       R_DrawRTLight(&light->rtlight, visiblelighting, visiblevolumes);
 
-       if (visiblevolumes)
+       if (visiblelighting || visiblevolumes)
        {
                qglEnable(GL_CULL_FACE);
                GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
index 8688f7ed238d5e3be9e9a6d6f3bd37c88d11f876..571f81d1a4ca43b845ae2cbb13bbc082cb50a493 100644 (file)
@@ -20,12 +20,15 @@ extern cvar_t r_shadow_realtime_world;
 extern cvar_t r_shadow_realtime_world_dlightshadows;
 extern cvar_t r_shadow_realtime_world_lightmaps;
 extern cvar_t r_shadow_realtime_world_shadows;
+extern cvar_t r_shadow_realtime_world_compile;
+extern cvar_t r_shadow_realtime_world_compilelight;
+extern cvar_t r_shadow_realtime_world_compileshadow;
 extern cvar_t r_shadow_scissor;
 extern cvar_t r_shadow_shadow_polygonfactor;
 extern cvar_t r_shadow_shadow_polygonoffset;
 extern cvar_t r_shadow_singlepassvolumegeneration;
-extern cvar_t r_shadow_staticworldlights;
 extern cvar_t r_shadow_texture3d;
+extern cvar_t r_shadow_visiblelighting;
 extern cvar_t r_shadow_visiblevolumes;
 extern cvar_t gl_ext_stenciltwoside;
 
@@ -34,7 +37,7 @@ extern mempool_t *r_shadow_mempool;
 void R_Shadow_Init(void);
 void R_Shadow_VolumeFromList(int numverts, int numtris, const float *invertex3f, const int *elements, const int *neighbors, const vec3_t projectorigin, float projectdistance, int nummarktris, const int *marktris);
 void R_Shadow_MarkVolumeFromBox(int firsttriangle, int numtris, const float *invertex3f, const int *elements, const vec3_t projectorigin, const vec3_t lightmins, const vec3_t lightmaxs, const vec3_t surfacemins, const vec3_t surfacemaxs);
-void R_Shadow_RenderLighting(int firstvertex, int numvertices, int numtriangles, const int *elements, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const float *texcoord2f, const float *relativelightorigin, const float *relativeeyeorigin, const float *lightcolorbase, const float *lightcolorpants, const float *lightcolorshirt, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *bumptexture, rtexture_t *glosstexture, rtexture_t *lightcubemap, vec_t ambientscale, vec_t diffusescale, vec_t specularscale);
+void R_Shadow_RenderLighting(int firstvertex, int numvertices, int numtriangles, const int *elements, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const float *texcoord2f, const float *relativelightorigin, const float *relativeeyeorigin, const float *lightcolorbase, const float *lightcolorpants, const float *lightcolorshirt, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *bumptexture, rtexture_t *glosstexture, rtexture_t *lightcubemap, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int visiblelighting);
 void R_Shadow_ClearStencil(void);
 
 void R_Shadow_RenderVolume(int numvertices, int numtriangles, const float *vertex3f, const int *element3i);
@@ -56,7 +59,7 @@ void R_RTLight_UpdateFromDLight(rtlight_t *rtlight, const dlight_t *light, int i
 void R_RTLight_Compile(rtlight_t *rtlight);
 void R_RTLight_Uncompile(rtlight_t *rtlight);
 
-void R_ShadowVolumeLighting(int visiblevolumes);
+void R_ShadowVolumeLighting(int visiblelighting, int visiblevolumes);
 
 int *R_Shadow_ResizeShadowElements(int numtris);