]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - r_shadow.c
implemented occlusion query support on corona rendering, this enables
[xonotic/darkplaces.git] / r_shadow.c
index 4964cf58e648f620326e08072102385e655f524e..cfb1d58a19956224e4c2e5bcd62b02d221b9bd0a 100644 (file)
@@ -178,6 +178,7 @@ int *vertexremap;
 int vertexupdatenum;
 
 int r_shadow_buffer_numleafpvsbytes;
+unsigned char *r_shadow_buffer_visitingleafpvs;
 unsigned char *r_shadow_buffer_leafpvs;
 int *r_shadow_buffer_leaflist;
 
@@ -210,6 +211,7 @@ cvar_t r_shadow_gloss = {CVAR_SAVE, "r_shadow_gloss", "1", "0 disables gloss (sp
 cvar_t r_shadow_gloss2intensity = {0, "r_shadow_gloss2intensity", "0.125", "how bright the forced flat gloss should look if r_shadow_gloss is 2"};
 cvar_t r_shadow_glossintensity = {0, "r_shadow_glossintensity", "1", "how bright textured glossmaps should look if r_shadow_gloss is 1 or 2"};
 cvar_t r_shadow_glossexponent = {0, "r_shadow_glossexponent", "32", "how 'sharp' the gloss should appear (specular power)"};
+cvar_t r_shadow_glossexact = {0, "r_shadow_glossexact", "1", "use exact reflection math for gloss (slightly slower, but should look a tad better)"};
 cvar_t r_shadow_lightattenuationdividebias = {0, "r_shadow_lightattenuationdividebias", "1", "changes attenuation texture generation"};
 cvar_t r_shadow_lightattenuationlinearscale = {0, "r_shadow_lightattenuationlinearscale", "2", "changes attenuation texture generation"};
 cvar_t r_shadow_lightintensityscale = {0, "r_shadow_lightintensityscale", "1", "renders all world lights brighter or darker"};
@@ -234,6 +236,8 @@ cvar_t r_shadow_polygonfactor = {0, "r_shadow_polygonfactor", "0", "how much to
 cvar_t r_shadow_polygonoffset = {0, "r_shadow_polygonoffset", "1", "how much to push shadow volumes into the distance when rendering, to reduce chances of zfighting artifacts (should not be less than 0)"};
 cvar_t r_shadow_texture3d = {0, "r_shadow_texture3d", "1", "use 3D voxel textures for spherical attenuation rather than cylindrical (does not affect r_glsl lighting)"};
 cvar_t r_coronas = {CVAR_SAVE, "r_coronas", "1", "brightness of corona flare effects around certain lights, 0 disables corona effects"};
+cvar_t r_coronas_occlusionsizescale = {CVAR_SAVE, "r_coronas_occlusionsizescale", "0.1", "size of light source for corona occlusion checksm the proportion of hidden pixels controls corona intensity"};
+cvar_t r_coronas_occlusionquery = {CVAR_SAVE, "r_coronas_occlusionquery", "1", "use GL_ARB_occlusion_query extension if supported (fades coronas according to visibility)"};
 cvar_t gl_flashblend = {CVAR_SAVE, "gl_flashblend", "0", "render bright coronas for dynamic lights instead of actual lighting, fast but ugly"};
 cvar_t gl_ext_separatestencil = {0, "gl_ext_separatestencil", "1", "make use of OpenGL 2.0 glStencilOpSeparate or GL_ATI_separate_stencil extension"};
 cvar_t gl_ext_stenciltwoside = {0, "gl_ext_stenciltwoside", "1", "make use of GL_EXT_stenciltwoside extension (NVIDIA only)"};
@@ -318,6 +322,7 @@ void r_shadow_start(void)
        shadowmarklist = NULL;
        shadowmarkcount = 0;
        r_shadow_buffer_numleafpvsbytes = 0;
+       r_shadow_buffer_visitingleafpvs = NULL;
        r_shadow_buffer_leafpvs = NULL;
        r_shadow_buffer_leaflist = NULL;
        r_shadow_buffer_numsurfacepvsbytes = 0;
@@ -363,6 +368,9 @@ void r_shadow_shutdown(void)
        shadowmarklist = NULL;
        shadowmarkcount = 0;
        r_shadow_buffer_numleafpvsbytes = 0;
+       if (r_shadow_buffer_visitingleafpvs)
+               Mem_Free(r_shadow_buffer_visitingleafpvs);
+       r_shadow_buffer_visitingleafpvs = NULL;
        if (r_shadow_buffer_leafpvs)
                Mem_Free(r_shadow_buffer_leafpvs);
        r_shadow_buffer_leafpvs = NULL;
@@ -386,6 +394,8 @@ void r_shadow_shutdown(void)
 
 void r_shadow_newmap(void)
 {
+       if (cl.worldmodel && strncmp(cl.worldmodel->name, r_shadow_mapname, sizeof(r_shadow_mapname)))
+               R_Shadow_EditLights_Reload_f();
 }
 
 void R_Shadow_Help_f(void)
@@ -433,6 +443,7 @@ void R_Shadow_Init(void)
        Cvar_RegisterVariable(&r_shadow_gloss2intensity);
        Cvar_RegisterVariable(&r_shadow_glossintensity);
        Cvar_RegisterVariable(&r_shadow_glossexponent);
+       Cvar_RegisterVariable(&r_shadow_glossexact);
        Cvar_RegisterVariable(&r_shadow_lightattenuationdividebias);
        Cvar_RegisterVariable(&r_shadow_lightattenuationlinearscale);
        Cvar_RegisterVariable(&r_shadow_lightintensityscale);
@@ -457,6 +468,8 @@ void R_Shadow_Init(void)
        Cvar_RegisterVariable(&r_shadow_polygonoffset);
        Cvar_RegisterVariable(&r_shadow_texture3d);
        Cvar_RegisterVariable(&r_coronas);
+       Cvar_RegisterVariable(&r_coronas_occlusionsizescale);
+       Cvar_RegisterVariable(&r_coronas_occlusionquery);
        Cvar_RegisterVariable(&gl_flashblend);
        Cvar_RegisterVariable(&gl_ext_separatestencil);
        Cvar_RegisterVariable(&gl_ext_stenciltwoside);
@@ -482,6 +495,7 @@ void R_Shadow_Init(void)
        shadowmarklist = NULL;
        shadowmarkcount = 0;
        r_shadow_buffer_numleafpvsbytes = 0;
+       r_shadow_buffer_visitingleafpvs = NULL;
        r_shadow_buffer_leafpvs = NULL;
        r_shadow_buffer_leaflist = NULL;
        r_shadow_buffer_numsurfacepvsbytes = 0;
@@ -540,11 +554,14 @@ static void R_Shadow_EnlargeLeafSurfaceTrisBuffer(int numleafs, int numsurfaces,
        int numlighttrispvsbytes = (((numlighttriangles + 7) >> 3) + 255) & ~255;
        if (r_shadow_buffer_numleafpvsbytes < numleafpvsbytes)
        {
+               if (r_shadow_buffer_visitingleafpvs)
+                       Mem_Free(r_shadow_buffer_visitingleafpvs);
                if (r_shadow_buffer_leafpvs)
                        Mem_Free(r_shadow_buffer_leafpvs);
                if (r_shadow_buffer_leaflist)
                        Mem_Free(r_shadow_buffer_leaflist);
                r_shadow_buffer_numleafpvsbytes = numleafpvsbytes;
+               r_shadow_buffer_visitingleafpvs = (unsigned char *)Mem_Alloc(r_main_mempool, r_shadow_buffer_numleafpvsbytes);
                r_shadow_buffer_leafpvs = (unsigned char *)Mem_Alloc(r_main_mempool, r_shadow_buffer_numleafpvsbytes);
                r_shadow_buffer_leaflist = (int *)Mem_Alloc(r_main_mempool, r_shadow_buffer_numleafpvsbytes * 8 * sizeof(*r_shadow_buffer_leaflist));
        }
@@ -611,28 +628,6 @@ int R_Shadow_ConstructShadowVolume(int innumvertices, int innumtris, const int *
        else
                VectorClear(projectvector);
 
-       if (maxvertexupdate < innumvertices)
-       {
-               maxvertexupdate = innumvertices;
-               if (vertexupdate)
-                       Mem_Free(vertexupdate);
-               if (vertexremap)
-                       Mem_Free(vertexremap);
-               vertexupdate = (int *)Mem_Alloc(r_main_mempool, maxvertexupdate * sizeof(int));
-               vertexremap = (int *)Mem_Alloc(r_main_mempool, maxvertexupdate * sizeof(int));
-               vertexupdatenum = 0;
-       }
-       vertexupdatenum++;
-       if (vertexupdatenum == 0)
-       {
-               vertexupdatenum = 1;
-               memset(vertexupdate, 0, maxvertexupdate * sizeof(int));
-               memset(vertexremap, 0, maxvertexupdate * sizeof(int));
-       }
-
-       for (i = 0;i < numshadowmarktris;i++)
-               shadowmark[shadowmarktris[i]] = shadowmarkcount;
-
        // create the vertices
        if (projectdirection)
        {
@@ -817,24 +812,6 @@ int R_Shadow_ConstructShadowVolume(int innumvertices, int innumtris, const int *
        return outtriangles;
 }
 
-void R_Shadow_VolumeFromList(int numverts, int numtris, const float *invertex3f, const int *elements, const int *neighbors, const vec3_t projectorigin, const vec3_t projectdirection, float projectdistance, int nummarktris, const int *marktris)
-{
-       int tris, outverts;
-       if (projectdistance < 0.1)
-       {
-               Con_Printf("R_Shadow_Volume: projectdistance %f\n", projectdistance);
-               return;
-       }
-       if (!numverts || !nummarktris)
-               return;
-       // make sure shadowelements is big enough for this volume
-       if (maxshadowtriangles < nummarktris || maxshadowvertices < numverts)
-               R_Shadow_ResizeShadowArrays((numverts + 255) & ~255, (nummarktris + 255) & ~255);
-       tris = R_Shadow_ConstructShadowVolume(numverts, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, shadowvertex3f, projectorigin, projectdirection, projectdistance, nummarktris, marktris);
-       r_refdef.stats.lights_dynamicshadowtriangles += tris;
-       R_Shadow_RenderVolume(outverts, tris, shadowvertex3f, shadowelements);
-}
-
 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 t, tend;
@@ -894,31 +871,70 @@ void R_Shadow_MarkVolumeFromBox(int firsttriangle, int numtris, const float *inv
        }
 }
 
-void R_Shadow_RenderVolume(int numvertices, int numtriangles, const float *vertex3f, const int *element3i)
+void R_Shadow_VolumeFromList(int numverts, int numtris, const float *invertex3f, const int *elements, const int *neighbors, const vec3_t projectorigin, const vec3_t projectdirection, float projectdistance, int nummarktris, const int *marktris, vec3_t trismins, vec3_t trismaxs)
 {
+       int i, tris, outverts;
+       if (projectdistance < 0.1)
+       {
+               Con_Printf("R_Shadow_Volume: projectdistance %f\n", projectdistance);
+               return;
+       }
+       if (!numverts || !nummarktris)
+               return;
+       // make sure shadowelements is big enough for this volume
+       if (maxshadowtriangles < nummarktris || maxshadowvertices < numverts)
+               R_Shadow_ResizeShadowArrays((numverts + 255) & ~255, (nummarktris + 255) & ~255);
+
+       if (maxvertexupdate < numverts)
+       {
+               maxvertexupdate = numverts;
+               if (vertexupdate)
+                       Mem_Free(vertexupdate);
+               if (vertexremap)
+                       Mem_Free(vertexremap);
+               vertexupdate = (int *)Mem_Alloc(r_main_mempool, maxvertexupdate * sizeof(int));
+               vertexremap = (int *)Mem_Alloc(r_main_mempool, maxvertexupdate * sizeof(int));
+               vertexupdatenum = 0;
+       }
+       vertexupdatenum++;
+       if (vertexupdatenum == 0)
+       {
+               vertexupdatenum = 1;
+               memset(vertexupdate, 0, maxvertexupdate * sizeof(int));
+               memset(vertexremap, 0, maxvertexupdate * sizeof(int));
+       }
+
+       for (i = 0;i < nummarktris;i++)
+               shadowmark[marktris[i]] = shadowmarkcount;
+
        if (r_shadow_compilingrtlight)
        {
                // if we're compiling an rtlight, capture the mesh
-               Mod_ShadowMesh_AddMesh(r_main_mempool, r_shadow_compilingrtlight->static_meshchain_shadow, NULL, NULL, NULL, vertex3f, NULL, NULL, NULL, NULL, numtriangles, element3i);
-               return;
+               tris = R_Shadow_ConstructShadowVolume(numverts, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, shadowvertex3f, projectorigin, projectdirection, projectdistance, nummarktris, marktris);
+               Mod_ShadowMesh_AddMesh(r_main_mempool, r_shadow_compilingrtlight->static_meshchain_shadow, NULL, NULL, NULL, shadowvertex3f, NULL, NULL, NULL, NULL, tris, shadowelements);
        }
-       r_refdef.stats.lights_shadowtriangles += numtriangles;
-       CHECKGLERROR
-       R_Mesh_VertexPointer(vertex3f, 0, 0);
-       GL_LockArrays(0, numvertices);
-       if (r_shadow_rendermode == R_SHADOW_RENDERMODE_STENCIL)
+       else
        {
-               // decrement stencil if backface is behind depthbuffer
-               GL_CullFace(r_view.cullface_front);
-               qglStencilOp(GL_KEEP, GL_DECR, GL_KEEP);CHECKGLERROR
-               R_Mesh_Draw(0, numvertices, numtriangles, element3i, 0, 0);
-               // increment stencil if frontface is behind depthbuffer
-               GL_CullFace(r_view.cullface_back);
-               qglStencilOp(GL_KEEP, GL_INCR, GL_KEEP);CHECKGLERROR
+               tris = R_Shadow_ConstructShadowVolume(numverts, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, shadowvertex3f, projectorigin, projectdirection, projectdistance, nummarktris, marktris);
+               r_refdef.stats.lights_dynamicshadowtriangles += tris;
+               r_refdef.stats.lights_shadowtriangles += tris;
+               CHECKGLERROR
+               R_Mesh_VertexPointer(shadowvertex3f, 0, 0);
+               GL_LockArrays(0, outverts);
+               if (r_shadow_rendermode == R_SHADOW_RENDERMODE_STENCIL)
+               {
+                       // decrement stencil if backface is behind depthbuffer
+                       GL_CullFace(r_refdef.view.cullface_front);
+                       qglStencilOp(GL_KEEP, GL_DECR, GL_KEEP);CHECKGLERROR
+                       R_Mesh_Draw(0, outverts, 0, tris, shadowelements, NULL, 0, 0);
+                       // increment stencil if frontface is behind depthbuffer
+                       GL_CullFace(r_refdef.view.cullface_back);
+                       qglStencilOp(GL_KEEP, GL_INCR, GL_KEEP);CHECKGLERROR
+               }
+               R_Mesh_Draw(0, outverts, 0, tris, shadowelements, NULL, 0, 0);
+               GL_LockArrays(0, 0);
+               CHECKGLERROR
        }
-       R_Mesh_Draw(0, numvertices, numtriangles, element3i, 0, 0);
-       GL_LockArrays(0, 0);
-       CHECKGLERROR
 }
 
 static void R_Shadow_MakeTextures_MakeCorona(void)
@@ -993,12 +1009,12 @@ static void R_Shadow_MakeTextures(void)
        R_Shadow_MakeTextures_MakeCorona();
 
        // Editor light sprites
-       r_editlights_sprcursor = Draw_CachePic("gfx/editlights/cursor", true);
-       r_editlights_sprlight = Draw_CachePic("gfx/editlights/light", true);
-       r_editlights_sprnoshadowlight = Draw_CachePic("gfx/editlights/noshadow", true);
-       r_editlights_sprcubemaplight = Draw_CachePic("gfx/editlights/cubemaplight", true);
-       r_editlights_sprcubemapnoshadowlight = Draw_CachePic("gfx/editlights/cubemapnoshadowlight", true);
-       r_editlights_sprselection = Draw_CachePic("gfx/editlights/selection", true);
+       r_editlights_sprcursor = Draw_CachePic ("gfx/editlights/cursor");
+       r_editlights_sprlight = Draw_CachePic ("gfx/editlights/light");
+       r_editlights_sprnoshadowlight = Draw_CachePic ("gfx/editlights/noshadow");
+       r_editlights_sprcubemaplight = Draw_CachePic ("gfx/editlights/cubemaplight");
+       r_editlights_sprcubemapnoshadowlight = Draw_CachePic ("gfx/editlights/cubemapnoshadowlight");
+       r_editlights_sprselection = Draw_CachePic ("gfx/editlights/selection");
 }
 
 void R_Shadow_ValidateCvars(void)
@@ -1030,7 +1046,7 @@ void R_Shadow_RenderMode_Begin(void)
        GL_DepthTest(true);
        GL_DepthMask(false);
        GL_Color(0, 0, 0, 1);
-       GL_Scissor(r_view.x, r_view.y, r_view.width, r_view.height);
+       GL_Scissor(r_refdef.view.x, r_refdef.view.y, r_refdef.view.width, r_refdef.view.height);
 
        r_shadow_rendermode = R_SHADOW_RENDERMODE_NONE;
 
@@ -1049,7 +1065,7 @@ void R_Shadow_RenderMode_Begin(void)
                r_shadow_lightingrendermode = R_SHADOW_RENDERMODE_LIGHT_VERTEX;
 }
 
-void R_Shadow_RenderMode_ActiveLight(rtlight_t *rtlight)
+void R_Shadow_RenderMode_ActiveLight(const rtlight_t *rtlight)
 {
        rsurface.rtlight = rtlight;
 }
@@ -1057,11 +1073,7 @@ void R_Shadow_RenderMode_ActiveLight(rtlight_t *rtlight)
 void R_Shadow_RenderMode_Reset(void)
 {
        CHECKGLERROR
-       if (r_shadow_rendermode == R_SHADOW_RENDERMODE_LIGHT_GLSL)
-       {
-               qglUseProgramObjectARB(0);CHECKGLERROR
-       }
-       else if (r_shadow_rendermode == R_SHADOW_RENDERMODE_STENCILTWOSIDE)
+       if (r_shadow_rendermode == R_SHADOW_RENDERMODE_STENCILTWOSIDE)
        {
                qglDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
        }
@@ -1076,41 +1088,47 @@ void R_Shadow_RenderMode_Reset(void)
        qglStencilMask(~0);CHECKGLERROR
        qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);CHECKGLERROR
        qglStencilFunc(GL_ALWAYS, 128, ~0);CHECKGLERROR
-       GL_CullFace(r_view.cullface_back);
+       GL_CullFace(r_refdef.view.cullface_back);
        GL_Color(1, 1, 1, 1);
-       GL_ColorMask(r_view.colormask[0], r_view.colormask[1], r_view.colormask[2], 1);
+       GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1);
        GL_BlendFunc(GL_ONE, GL_ZERO);
+       R_SetupGenericShader(false);
+}
+
+void R_Shadow_ClearStencil(void)
+{
+       CHECKGLERROR
+       GL_Clear(GL_STENCIL_BUFFER_BIT);
+       r_refdef.stats.lights_clears++;
 }
 
-void R_Shadow_RenderMode_StencilShadowVolumes(qboolean clearstencil)
+void R_Shadow_RenderMode_StencilShadowVolumes(void)
 {
        CHECKGLERROR
        R_Shadow_RenderMode_Reset();
        GL_ColorMask(0, 0, 0, 0);
        GL_PolygonOffset(r_refdef.shadowpolygonfactor, r_refdef.shadowpolygonoffset);CHECKGLERROR
+       R_SetupDepthOrShadowShader();
        qglDepthFunc(GL_LESS);CHECKGLERROR
        qglEnable(GL_STENCIL_TEST);CHECKGLERROR
        r_shadow_rendermode = r_shadow_shadowingrendermode;
        if (r_shadow_rendermode == R_SHADOW_RENDERMODE_SEPARATESTENCIL)
        {
                GL_CullFace(GL_NONE);
-               qglStencilOpSeparate(r_view.cullface_front, GL_KEEP, GL_INCR, GL_KEEP);CHECKGLERROR
-               qglStencilOpSeparate(r_view.cullface_back, GL_KEEP, GL_DECR, GL_KEEP);CHECKGLERROR
+               qglStencilOpSeparate(r_refdef.view.cullface_front, GL_KEEP, GL_INCR, GL_KEEP);CHECKGLERROR
+               qglStencilOpSeparate(r_refdef.view.cullface_back, GL_KEEP, GL_DECR, GL_KEEP);CHECKGLERROR
        }
        else if (r_shadow_rendermode == R_SHADOW_RENDERMODE_STENCILTWOSIDE)
        {
                GL_CullFace(GL_NONE);
                qglEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
-               qglActiveStencilFaceEXT(r_view.cullface_front);CHECKGLERROR
+               qglActiveStencilFaceEXT(r_refdef.view.cullface_front);CHECKGLERROR
                qglStencilMask(~0);CHECKGLERROR
                qglStencilOp(GL_KEEP, GL_INCR, GL_KEEP);CHECKGLERROR
-               qglActiveStencilFaceEXT(r_view.cullface_back);CHECKGLERROR
+               qglActiveStencilFaceEXT(r_refdef.view.cullface_back);CHECKGLERROR
                qglStencilMask(~0);CHECKGLERROR
                qglStencilOp(GL_KEEP, GL_DECR, GL_KEEP);CHECKGLERROR
        }
-       if (clearstencil)
-               GL_Clear(GL_STENCIL_BUFFER_BIT);
-       r_refdef.stats.lights_clears++;
 }
 
 void R_Shadow_RenderMode_Lighting(qboolean stenciltest, qboolean transparent)
@@ -1133,21 +1151,12 @@ void R_Shadow_RenderMode_Lighting(qboolean stenciltest, qboolean transparent)
        // do global setup needed for the chosen lighting mode
        if (r_shadow_rendermode == R_SHADOW_RENDERMODE_LIGHT_GLSL)
        {
-               R_Mesh_TexBind(0, R_GetTexture(r_texture_blanknormalmap)); // normal
-               R_Mesh_TexBind(1, R_GetTexture(r_texture_white)); // diffuse
-               R_Mesh_TexBind(2, R_GetTexture(r_texture_white)); // gloss
-               R_Mesh_TexBindCubeMap(3, R_GetTexture(rsurface.rtlight->currentcubemap)); // light filter
-               R_Mesh_TexBind(4, R_GetTexture(r_texture_fogattenuation)); // fog
-               R_Mesh_TexBind(5, R_GetTexture(r_texture_white)); // pants
-               R_Mesh_TexBind(6, R_GetTexture(r_texture_white)); // shirt
-               R_Mesh_TexBind(7, R_GetTexture(r_texture_white)); // lightmap
-               R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap)); // deluxemap
-               R_Mesh_TexBind(9, R_GetTexture(r_texture_black)); // glow
-               //R_Mesh_TexMatrix(3, rsurface.entitytolight); // light filter matrix
-               GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
-               GL_ColorMask(r_view.colormask[0], r_view.colormask[1], r_view.colormask[2], 0);
-               CHECKGLERROR
+               R_Mesh_TexBindCubeMap(GL20TU_CUBE, R_GetTexture(rsurface.rtlight->currentcubemap)); // light filter
+               GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 0);
        }
+       else if (r_shadow_rendermode == R_SHADOW_RENDERMODE_LIGHT_VERTEX)
+               R_Mesh_ColorPointer(rsurface.array_color4f, 0, 0);
+       GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
 }
 
 void R_Shadow_RenderMode_VisibleShadowVolumes(void)
@@ -1157,7 +1166,7 @@ void R_Shadow_RenderMode_VisibleShadowVolumes(void)
        GL_BlendFunc(GL_ONE, GL_ONE);
        GL_DepthRange(0, 1);
        GL_DepthTest(r_showshadowvolumes.integer < 2);
-       GL_Color(0.0, 0.0125 * r_view.colorscale, 0.1 * r_view.colorscale, 1);
+       GL_Color(0.0, 0.0125 * r_refdef.view.colorscale, 0.1 * r_refdef.view.colorscale, 1);
        GL_PolygonOffset(r_refdef.shadowpolygonfactor, r_refdef.shadowpolygonoffset);CHECKGLERROR
        GL_CullFace(GL_NONE);
        r_shadow_rendermode = R_SHADOW_RENDERMODE_VISIBLEVOLUMES;
@@ -1170,7 +1179,7 @@ void R_Shadow_RenderMode_VisibleLighting(qboolean stenciltest, qboolean transpar
        GL_BlendFunc(GL_ONE, GL_ONE);
        GL_DepthRange(0, 1);
        GL_DepthTest(r_showlighting.integer < 2);
-       GL_Color(0.1 * r_view.colorscale, 0.0125 * r_view.colorscale, 0, 1);
+       GL_Color(0.1 * r_refdef.view.colorscale, 0.0125 * r_refdef.view.colorscale, 0, 1);
        if (!transparent)
        {
                qglDepthFunc(GL_EQUAL);CHECKGLERROR
@@ -1189,7 +1198,7 @@ void R_Shadow_RenderMode_End(void)
        R_Shadow_RenderMode_Reset();
        R_Shadow_RenderMode_ActiveLight(NULL);
        GL_DepthMask(true);
-       GL_Scissor(r_view.x, r_view.y, r_view.width, r_view.height);
+       GL_Scissor(r_refdef.view.x, r_refdef.view.y, r_refdef.view.width, r_refdef.view.height);
        r_shadow_rendermode = R_SHADOW_RENDERMODE_NONE;
 }
 
@@ -1230,17 +1239,17 @@ qboolean R_Shadow_ScissorForBBox(const float *mins, const float *maxs)
                return false;
 
        // if view is inside the light box, just say yes it's visible
-       if (BoxesOverlap(r_view.origin, r_view.origin, mins, maxs))
+       if (BoxesOverlap(r_refdef.view.origin, r_refdef.view.origin, mins, maxs))
        {
-               GL_Scissor(r_view.x, r_view.y, r_view.width, r_view.height);
+               GL_Scissor(r_refdef.view.x, r_refdef.view.y, r_refdef.view.width, r_refdef.view.height);
                return false;
        }
 
        x1 = y1 = x2 = y2 = 0;
 
        // transform all corners that are infront of the nearclip plane
-       VectorNegate(r_view.frustum[4].normal, plane4f);
-       plane4f[3] = r_view.frustum[4].dist;
+       VectorNegate(r_refdef.view.frustum[4].normal, plane4f);
+       plane4f[3] = r_refdef.view.frustum[4].dist;
        numvertices = 0;
        for (i = 0;i < 8;i++)
        {
@@ -1306,10 +1315,10 @@ qboolean R_Shadow_ScissorForBBox(const float *mins, const float *maxs)
        //Con_Printf("%f %f %f %f\n", x1, y1, x2, y2);
 
        // clamp it to the screen
-       if (ix1 < r_view.x) ix1 = r_view.x;
-       if (iy1 < r_view.y) iy1 = r_view.y;
-       if (ix2 > r_view.x + r_view.width) ix2 = r_view.x + r_view.width;
-       if (iy2 > r_view.y + r_view.height) iy2 = r_view.y + r_view.height;
+       if (ix1 < r_refdef.view.x) ix1 = r_refdef.view.x;
+       if (iy1 < r_refdef.view.y) iy1 = r_refdef.view.y;
+       if (ix2 > r_refdef.view.x + r_refdef.view.width) ix2 = r_refdef.view.x + r_refdef.view.width;
+       if (iy2 > r_refdef.view.y + r_refdef.view.height) iy2 = r_refdef.view.y + r_refdef.view.height;
 
        // if it is inside out, it's not visible
        if (ix2 <= ix1 || iy2 <= iy1)
@@ -1533,28 +1542,38 @@ static void R_Shadow_GenTexCoords_Specular_NormalCubeMap(int firstvertex, int nu
        }
 }
 
-static void R_Shadow_RenderLighting_VisibleLighting(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt)
+static void R_Shadow_RenderLighting_VisibleLighting(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const unsigned short *element3s, int element3i_bufferobject, int element3s_bufferobject, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt)
 {
        // used to display how many times a surface is lit for level design purposes
-       GL_Color(0.1 * r_view.colorscale, 0.025 * r_view.colorscale, 0, 1);
-       R_Mesh_ColorPointer(NULL, 0, 0);
-       R_Mesh_ResetTextureState();
-       R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+       R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 }
 
-static void R_Shadow_RenderLighting_Light_GLSL(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt)
+static void R_Shadow_RenderLighting_Light_GLSL(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const unsigned short *element3s, int element3i_bufferobject, int element3s_bufferobject, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt)
 {
        // ARB2 GLSL shader path (GFFX5200, Radeon 9500)
        R_SetupSurfaceShader(lightcolorbase, false, ambientscale, diffusescale, specularscale, RSURFPASS_RTLIGHT);
+       if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND))
+               R_Mesh_ColorPointer(rsurface.modellightmapcolor4f, rsurface.modellightmapcolor4f_bufferobject, rsurface.modellightmapcolor4f_bufferoffset);
+       else
+               R_Mesh_ColorPointer(NULL, 0, 0);
        R_Mesh_TexMatrix(0, &rsurface.texture->currenttexmatrix);
-       R_Mesh_TexBind(0, R_GetTexture(rsurface.texture->currentskinframe->nmap));
-       R_Mesh_TexBind(1, R_GetTexture(rsurface.texture->basetexture));
-       R_Mesh_TexBind(2, R_GetTexture(rsurface.texture->glosstexture));
-       R_Mesh_TexBindCubeMap(3, R_GetTexture(rsurface.rtlight->currentcubemap));
-       R_Mesh_TexBind(4, R_GetTexture(r_texture_fogattenuation));
-       R_Mesh_TexBind(5, R_GetTexture(rsurface.texture->currentskinframe->pants));
-       R_Mesh_TexBind(6, R_GetTexture(rsurface.texture->currentskinframe->shirt));
-       R_Mesh_TexBind(10, R_GetTexture(r_shadow_attenuationgradienttexture));
+       R_Mesh_TexBind(GL20TU_NORMAL, R_GetTexture(rsurface.texture->currentskinframe->nmap));
+       R_Mesh_TexBind(GL20TU_COLOR, R_GetTexture(rsurface.texture->basetexture));
+       R_Mesh_TexBind(GL20TU_GLOSS, R_GetTexture(rsurface.texture->glosstexture));
+       if (rsurface.texture->backgroundcurrentskinframe)
+       {
+               R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL, R_GetTexture(rsurface.texture->backgroundcurrentskinframe->nmap));
+               R_Mesh_TexBind(GL20TU_SECONDARY_COLOR, R_GetTexture(rsurface.texture->backgroundbasetexture));
+               R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS, R_GetTexture(rsurface.texture->backgroundglosstexture));
+       }
+       //R_Mesh_TexBindCubeMap(GL20TU_CUBE, R_GetTexture(rsurface.rtlight->currentcubemap));
+       R_Mesh_TexBind(GL20TU_FOGMASK, R_GetTexture(r_texture_fogattenuation));
+       if(rsurface.texture->colormapping)
+       {
+               R_Mesh_TexBind(GL20TU_PANTS, R_GetTexture(rsurface.texture->currentskinframe->pants));
+               R_Mesh_TexBind(GL20TU_SHIRT, R_GetTexture(rsurface.texture->currentskinframe->shirt));
+       }
+       R_Mesh_TexBind(GL20TU_ATTENUATION, R_GetTexture(r_shadow_attenuationgradienttexture));
        R_Mesh_TexCoordPointer(0, 2, rsurface.texcoordtexture2f, rsurface.texcoordtexture2f_bufferobject, rsurface.texcoordtexture2f_bufferoffset);
        R_Mesh_TexCoordPointer(1, 3, rsurface.svector3f, rsurface.svector3f_bufferobject, rsurface.svector3f_bufferoffset);
        R_Mesh_TexCoordPointer(2, 3, rsurface.tvector3f, rsurface.tvector3f_bufferobject, rsurface.tvector3f_bufferoffset);
@@ -1563,26 +1582,26 @@ static void R_Shadow_RenderLighting_Light_GLSL(int firstvertex, int numvertices,
        {
                qglDepthFunc(GL_EQUAL);CHECKGLERROR
        }
-       R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+       R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
        if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
        {
                qglDepthFunc(GL_LEQUAL);CHECKGLERROR
        }
 }
 
-static void R_Shadow_RenderLighting_Light_Dot3_Finalize(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, float r, float g, float b)
+static void R_Shadow_RenderLighting_Light_Dot3_Finalize(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const unsigned short *element3s, int element3i_bufferobject, int element3s_bufferobject, float r, float g, float b)
 {
        // shared final code for all the dot3 layers
        int renders;
-       GL_ColorMask(r_view.colormask[0], r_view.colormask[1], r_view.colormask[2], 0);
+       GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 0);
        for (renders = 0;renders < 64 && (r > 0 || g > 0 || b > 0);renders++, r--, g--, b--)
        {
                GL_Color(bound(0, r, 1), bound(0, g, 1), bound(0, b, 1), 1);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
        }
 }
 
-static void R_Shadow_RenderLighting_Light_Dot3_AmbientPass(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, const vec3_t lightcolorbase, rtexture_t *basetexture, float colorscale)
+static void R_Shadow_RenderLighting_Light_Dot3_AmbientPass(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const unsigned short *element3s, int element3i_bufferobject, int element3s_bufferobject, const vec3_t lightcolorbase, rtexture_t *basetexture, float colorscale)
 {
        rmeshstate_t m;
        // colorscale accounts for how much we multiply the brightness
@@ -1697,7 +1716,7 @@ static void R_Shadow_RenderLighting_Light_Dot3_AmbientPass(int firstvertex, int
                R_Mesh_TextureState(&m);
                GL_ColorMask(0,0,0,1);
                GL_BlendFunc(GL_ONE, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // second pass
                memset(&m, 0, sizeof(m));
@@ -1718,10 +1737,10 @@ static void R_Shadow_RenderLighting_Light_Dot3_AmbientPass(int firstvertex, int
        }
        // this final code is shared
        R_Mesh_TextureState(&m);
-       R_Shadow_RenderLighting_Light_Dot3_Finalize(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase[0] * colorscale, lightcolorbase[1] * colorscale, lightcolorbase[2] * colorscale);
+       R_Shadow_RenderLighting_Light_Dot3_Finalize(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase[0] * colorscale, lightcolorbase[1] * colorscale, lightcolorbase[2] * colorscale);
 }
 
-static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, const vec3_t lightcolorbase, rtexture_t *basetexture, rtexture_t *normalmaptexture, float colorscale)
+static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const unsigned short *element3s, int element3i_bufferobject, int element3s_bufferobject, const vec3_t lightcolorbase, rtexture_t *basetexture, rtexture_t *normalmaptexture, float colorscale)
 {
        rmeshstate_t m;
        // colorscale accounts for how much we multiply the brightness
@@ -1757,7 +1776,7 @@ static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int
                R_Mesh_TextureState(&m);
                GL_ColorMask(0,0,0,1);
                GL_BlendFunc(GL_ONE, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // second pass
                memset(&m, 0, sizeof(m));
@@ -1788,7 +1807,7 @@ static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int
                R_Mesh_TextureState(&m);
                GL_ColorMask(0,0,0,1);
                GL_BlendFunc(GL_ONE, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // second pass
                memset(&m, 0, sizeof(m));
@@ -1805,7 +1824,7 @@ static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int
                m.pointer_texcoord_bufferoffset[1] = 0;
                R_Mesh_TextureState(&m);
                GL_BlendFunc(GL_DST_ALPHA, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // second pass
                memset(&m, 0, sizeof(m));
@@ -1842,7 +1861,7 @@ static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int
                R_Mesh_TextureState(&m);
                GL_ColorMask(0,0,0,1);
                GL_BlendFunc(GL_ONE, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // second pass
                memset(&m, 0, sizeof(m));
@@ -1886,7 +1905,7 @@ static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int
                R_Mesh_TextureState(&m);
                GL_ColorMask(0,0,0,1);
                GL_BlendFunc(GL_ONE, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // second pass
                memset(&m, 0, sizeof(m));
@@ -1922,7 +1941,7 @@ static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int
                R_Mesh_TextureState(&m);
                GL_ColorMask(0,0,0,1);
                GL_BlendFunc(GL_ONE, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // second pass
                memset(&m, 0, sizeof(m));
@@ -1939,7 +1958,7 @@ static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int
                m.pointer_texcoord_bufferoffset[1] = 0;
                R_Mesh_TextureState(&m);
                GL_BlendFunc(GL_DST_ALPHA, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // second pass
                memset(&m, 0, sizeof(m));
@@ -1960,10 +1979,10 @@ static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int
        }
        // this final code is shared
        R_Mesh_TextureState(&m);
-       R_Shadow_RenderLighting_Light_Dot3_Finalize(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase[0] * colorscale, lightcolorbase[1] * colorscale, lightcolorbase[2] * colorscale);
+       R_Shadow_RenderLighting_Light_Dot3_Finalize(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase[0] * colorscale, lightcolorbase[1] * colorscale, lightcolorbase[2] * colorscale);
 }
 
-static void R_Shadow_RenderLighting_Light_Dot3_SpecularPass(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, const vec3_t lightcolorbase, rtexture_t *glosstexture, rtexture_t *normalmaptexture, float colorscale)
+static void R_Shadow_RenderLighting_Light_Dot3_SpecularPass(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const unsigned short *element3s, int element3i_bufferobject, int element3s_bufferobject, const vec3_t lightcolorbase, rtexture_t *glosstexture, rtexture_t *normalmaptexture, float colorscale)
 {
        float glossexponent;
        rmeshstate_t m;
@@ -1991,14 +2010,14 @@ static void R_Shadow_RenderLighting_Light_Dot3_SpecularPass(int firstvertex, int
                GL_ColorMask(0,0,0,1);
                // this squares the result
                GL_BlendFunc(GL_SRC_ALPHA, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // second and third pass
                R_Mesh_ResetTextureState();
                // square alpha in framebuffer a few times to make it shiny
                GL_BlendFunc(GL_ZERO, GL_DST_ALPHA);
                for (glossexponent = 2;glossexponent * 2 <= r_shadow_glossexponent.value;glossexponent *= 2)
-                       R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+                       R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // fourth pass
                memset(&m, 0, sizeof(m));
@@ -2009,7 +2028,7 @@ static void R_Shadow_RenderLighting_Light_Dot3_SpecularPass(int firstvertex, int
                m.texmatrix[0] = rsurface.entitytoattenuationxyz;
                R_Mesh_TextureState(&m);
                GL_BlendFunc(GL_DST_ALPHA, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // fifth pass
                memset(&m, 0, sizeof(m));
@@ -2046,14 +2065,14 @@ static void R_Shadow_RenderLighting_Light_Dot3_SpecularPass(int firstvertex, int
                GL_ColorMask(0,0,0,1);
                // this squares the result
                GL_BlendFunc(GL_SRC_ALPHA, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // second and third pass
                R_Mesh_ResetTextureState();
                // square alpha in framebuffer a few times to make it shiny
                GL_BlendFunc(GL_ZERO, GL_DST_ALPHA);
                for (glossexponent = 2;glossexponent * 2 <= r_shadow_glossexponent.value;glossexponent *= 2)
-                       R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+                       R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // fourth pass
                memset(&m, 0, sizeof(m));
@@ -2087,14 +2106,14 @@ static void R_Shadow_RenderLighting_Light_Dot3_SpecularPass(int firstvertex, int
                GL_ColorMask(0,0,0,1);
                // this squares the result
                GL_BlendFunc(GL_SRC_ALPHA, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // second and third pass
                R_Mesh_ResetTextureState();
                // square alpha in framebuffer a few times to make it shiny
                GL_BlendFunc(GL_ZERO, GL_DST_ALPHA);
                for (glossexponent = 2;glossexponent * 2 <= r_shadow_glossexponent.value;glossexponent *= 2)
-                       R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+                       R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // fourth pass
                memset(&m, 0, sizeof(m));
@@ -2110,7 +2129,7 @@ static void R_Shadow_RenderLighting_Light_Dot3_SpecularPass(int firstvertex, int
                m.texmatrix[1] = rsurface.entitytoattenuationz;
                R_Mesh_TextureState(&m);
                GL_BlendFunc(GL_DST_ALPHA, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // fifth pass
                memset(&m, 0, sizeof(m));
@@ -2131,10 +2150,10 @@ static void R_Shadow_RenderLighting_Light_Dot3_SpecularPass(int firstvertex, int
        }
        // this final code is shared
        R_Mesh_TextureState(&m);
-       R_Shadow_RenderLighting_Light_Dot3_Finalize(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase[0] * colorscale, lightcolorbase[1] * colorscale, lightcolorbase[2] * colorscale);
+       R_Shadow_RenderLighting_Light_Dot3_Finalize(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase[0] * colorscale, lightcolorbase[1] * colorscale, lightcolorbase[2] * colorscale);
 }
 
-static void R_Shadow_RenderLighting_Light_Dot3(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt)
+static void R_Shadow_RenderLighting_Light_Dot3(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const unsigned short *element3s, int element3i_bufferobject, int element3s_bufferobject, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt)
 {
        // ARB path (any Geforce, any Radeon)
        qboolean doambient = ambientscale > 0;
@@ -2144,28 +2163,28 @@ static void R_Shadow_RenderLighting_Light_Dot3(int firstvertex, int numvertices,
                return;
        R_Mesh_ColorPointer(NULL, 0, 0);
        if (doambient)
-               R_Shadow_RenderLighting_Light_Dot3_AmbientPass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, basetexture, ambientscale * r_view.colorscale);
+               R_Shadow_RenderLighting_Light_Dot3_AmbientPass(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase, basetexture, ambientscale * r_refdef.view.colorscale);
        if (dodiffuse)
-               R_Shadow_RenderLighting_Light_Dot3_DiffusePass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, basetexture, normalmaptexture, diffusescale * r_view.colorscale);
+               R_Shadow_RenderLighting_Light_Dot3_DiffusePass(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase, basetexture, normalmaptexture, diffusescale * r_refdef.view.colorscale);
        if (dopants)
        {
                if (doambient)
-                       R_Shadow_RenderLighting_Light_Dot3_AmbientPass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorpants, pantstexture, ambientscale * r_view.colorscale);
+                       R_Shadow_RenderLighting_Light_Dot3_AmbientPass(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorpants, pantstexture, ambientscale * r_refdef.view.colorscale);
                if (dodiffuse)
-                       R_Shadow_RenderLighting_Light_Dot3_DiffusePass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorpants, pantstexture, normalmaptexture, diffusescale * r_view.colorscale);
+                       R_Shadow_RenderLighting_Light_Dot3_DiffusePass(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorpants, pantstexture, normalmaptexture, diffusescale * r_refdef.view.colorscale);
        }
        if (doshirt)
        {
                if (doambient)
-                       R_Shadow_RenderLighting_Light_Dot3_AmbientPass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorshirt, shirttexture, ambientscale * r_view.colorscale);
+                       R_Shadow_RenderLighting_Light_Dot3_AmbientPass(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorshirt, shirttexture, ambientscale * r_refdef.view.colorscale);
                if (dodiffuse)
-                       R_Shadow_RenderLighting_Light_Dot3_DiffusePass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorshirt, shirttexture, normalmaptexture, diffusescale * r_view.colorscale);
+                       R_Shadow_RenderLighting_Light_Dot3_DiffusePass(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorshirt, shirttexture, normalmaptexture, diffusescale * r_refdef.view.colorscale);
        }
        if (dospecular)
-               R_Shadow_RenderLighting_Light_Dot3_SpecularPass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, glosstexture, normalmaptexture, specularscale * r_view.colorscale);
+               R_Shadow_RenderLighting_Light_Dot3_SpecularPass(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase, glosstexture, normalmaptexture, specularscale * r_refdef.view.colorscale);
 }
 
-void R_Shadow_RenderLighting_Light_Vertex_Pass(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, vec3_t diffusecolor2, vec3_t ambientcolor2)
+static void R_Shadow_RenderLighting_Light_Vertex_Pass(int firstvertex, int numvertices, int numtriangles, const int *element3i, vec3_t diffusecolor2, vec3_t ambientcolor2)
 {
        int renders;
        int i;
@@ -2176,6 +2195,7 @@ void R_Shadow_RenderLighting_Light_Vertex_Pass(int firstvertex, int numvertices,
        int *newe;
        const int *e;
        float *c;
+       int maxtriangles = 4096;
        int newelements[4096*3];
        R_Shadow_RenderLighting_Light_Vertex_Shading(firstvertex, numvertices, numtriangles, element3i, diffusecolor2, ambientcolor2);
        for (renders = 0;renders < 64;renders++)
@@ -2213,9 +2233,9 @@ void R_Shadow_RenderLighting_Light_Vertex_Pass(int firstvertex, int numvertices,
                                newe[2] = e[2];
                                newnumtriangles++;
                                newe += 3;
-                               if (newnumtriangles >= (int)(sizeof(newelements)/sizeof(float[3])))
+                               if (newnumtriangles >= maxtriangles)
                                {
-                                       R_Mesh_Draw(newfirstvertex, newlastvertex - newfirstvertex + 1, newnumtriangles, newelements, 0, 0);
+                                       R_Mesh_Draw(newfirstvertex, newlastvertex - newfirstvertex + 1, 0, newnumtriangles, newelements, NULL, 0, 0);
                                        newnumtriangles = 0;
                                        newe = newelements;
                                        stop = false;
@@ -2224,11 +2244,7 @@ void R_Shadow_RenderLighting_Light_Vertex_Pass(int firstvertex, int numvertices,
                }
                if (newnumtriangles >= 1)
                {
-                       // if all triangles are included, use the original array to take advantage of the bufferobject if possible
-                       if (newnumtriangles == numtriangles)
-                               R_Mesh_Draw(newfirstvertex, newlastvertex - newfirstvertex + 1, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
-                       else
-                               R_Mesh_Draw(newfirstvertex, newlastvertex - newfirstvertex + 1, newnumtriangles, newelements, 0, 0);
+                       R_Mesh_Draw(newfirstvertex, newlastvertex - newfirstvertex + 1, 0, newnumtriangles, newelements, NULL, 0, 0);
                        stop = false;
                }
                // if we couldn't find any lit triangles, exit early
@@ -2257,21 +2273,19 @@ void R_Shadow_RenderLighting_Light_Vertex_Pass(int firstvertex, int numvertices,
        }
 }
 
-static void R_Shadow_RenderLighting_Light_Vertex(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt)
+static void R_Shadow_RenderLighting_Light_Vertex(int firstvertex, int numvertices, int numtriangles, const int *element3i, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt)
 {
        // OpenGL 1.1 path (anything)
        float ambientcolorbase[3], diffusecolorbase[3];
        float ambientcolorpants[3], diffusecolorpants[3];
        float ambientcolorshirt[3], diffusecolorshirt[3];
        rmeshstate_t m;
-       VectorScale(lightcolorbase, ambientscale * 2 * r_view.colorscale, ambientcolorbase);
-       VectorScale(lightcolorbase, diffusescale * 2 * r_view.colorscale, diffusecolorbase);
-       VectorScale(lightcolorpants, ambientscale * 2 * r_view.colorscale, ambientcolorpants);
-       VectorScale(lightcolorpants, diffusescale * 2 * r_view.colorscale, diffusecolorpants);
-       VectorScale(lightcolorshirt, ambientscale * 2 * r_view.colorscale, ambientcolorshirt);
-       VectorScale(lightcolorshirt, diffusescale * 2 * r_view.colorscale, diffusecolorshirt);
-       GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
-       R_Mesh_ColorPointer(rsurface.array_color4f, 0, 0);
+       VectorScale(lightcolorbase, ambientscale * 2 * r_refdef.view.colorscale, ambientcolorbase);
+       VectorScale(lightcolorbase, diffusescale * 2 * r_refdef.view.colorscale, diffusecolorbase);
+       VectorScale(lightcolorpants, ambientscale * 2 * r_refdef.view.colorscale, ambientcolorpants);
+       VectorScale(lightcolorpants, diffusescale * 2 * r_refdef.view.colorscale, diffusecolorpants);
+       VectorScale(lightcolorshirt, ambientscale * 2 * r_refdef.view.colorscale, ambientcolorshirt);
+       VectorScale(lightcolorshirt, diffusescale * 2 * r_refdef.view.colorscale, diffusecolorshirt);
        memset(&m, 0, sizeof(m));
        m.tex[0] = R_GetTexture(basetexture);
        m.texmatrix[0] = rsurface.texture->currenttexmatrix;
@@ -2298,21 +2312,21 @@ static void R_Shadow_RenderLighting_Light_Vertex(int firstvertex, int numvertice
        }
        R_Mesh_TextureState(&m);
        //R_Mesh_TexBind(0, R_GetTexture(basetexture));
-       R_Shadow_RenderLighting_Light_Vertex_Pass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, diffusecolorbase, ambientcolorbase);
+       R_Shadow_RenderLighting_Light_Vertex_Pass(firstvertex, numvertices, numtriangles, element3i, diffusecolorbase, ambientcolorbase);
        if (dopants)
        {
                R_Mesh_TexBind(0, R_GetTexture(pantstexture));
-               R_Shadow_RenderLighting_Light_Vertex_Pass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, diffusecolorpants, ambientcolorpants);
+               R_Shadow_RenderLighting_Light_Vertex_Pass(firstvertex, numvertices, numtriangles, element3i, diffusecolorpants, ambientcolorpants);
        }
        if (doshirt)
        {
                R_Mesh_TexBind(0, R_GetTexture(shirttexture));
-               R_Shadow_RenderLighting_Light_Vertex_Pass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, diffusecolorshirt, ambientcolorshirt);
+               R_Shadow_RenderLighting_Light_Vertex_Pass(firstvertex, numvertices, numtriangles, element3i, diffusecolorshirt, ambientcolorshirt);
        }
 }
 
 extern cvar_t gl_lightmaps;
-void R_Shadow_RenderLighting(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset)
+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)
 {
        float ambientscale, diffusescale, specularscale;
        vec3_t lightcolorbase, lightcolorpants, lightcolorshirt;
@@ -2360,16 +2374,16 @@ void R_Shadow_RenderLighting(int firstvertex, int numvertices, int numtriangles,
                {
                case R_SHADOW_RENDERMODE_VISIBLELIGHTING:
                        GL_DepthTest(!(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST) && !r_showdisabledepthtest.integer);
-                       R_Shadow_RenderLighting_VisibleLighting(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, lightcolorpants, lightcolorshirt, rsurface.texture->basetexture, rsurface.texture->currentskinframe->pants, rsurface.texture->currentskinframe->shirt, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, dopants, doshirt);
+                       R_Shadow_RenderLighting_VisibleLighting(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase, lightcolorpants, lightcolorshirt, rsurface.texture->basetexture, rsurface.texture->currentskinframe->pants, rsurface.texture->currentskinframe->shirt, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, dopants, doshirt);
                        break;
                case R_SHADOW_RENDERMODE_LIGHT_GLSL:
-                       R_Shadow_RenderLighting_Light_GLSL(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, lightcolorpants, lightcolorshirt, rsurface.texture->basetexture, rsurface.texture->currentskinframe->pants, rsurface.texture->currentskinframe->shirt, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, dopants, doshirt);
+                       R_Shadow_RenderLighting_Light_GLSL(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase, lightcolorpants, lightcolorshirt, rsurface.texture->basetexture, rsurface.texture->currentskinframe->pants, rsurface.texture->currentskinframe->shirt, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, dopants, doshirt);
                        break;
                case R_SHADOW_RENDERMODE_LIGHT_DOT3:
-                       R_Shadow_RenderLighting_Light_Dot3(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, lightcolorpants, lightcolorshirt, rsurface.texture->basetexture, rsurface.texture->currentskinframe->pants, rsurface.texture->currentskinframe->shirt, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, dopants, doshirt);
+                       R_Shadow_RenderLighting_Light_Dot3(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase, lightcolorpants, lightcolorshirt, rsurface.texture->basetexture, rsurface.texture->currentskinframe->pants, rsurface.texture->currentskinframe->shirt, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, dopants, doshirt);
                        break;
                case R_SHADOW_RENDERMODE_LIGHT_VERTEX:
-                       R_Shadow_RenderLighting_Light_Vertex(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, lightcolorpants, lightcolorshirt, rsurface.texture->basetexture, rsurface.texture->currentskinframe->pants, rsurface.texture->currentskinframe->shirt, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, dopants, doshirt);
+                       R_Shadow_RenderLighting_Light_Vertex(firstvertex, numvertices, numtriangles, element3i + firsttriangle * 3, lightcolorbase, lightcolorpants, lightcolorshirt, rsurface.texture->basetexture, rsurface.texture->currentskinframe->pants, rsurface.texture->currentskinframe->shirt, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, dopants, doshirt);
                        break;
                default:
                        Con_Printf("R_Shadow_RenderLighting: unknown r_shadow_rendermode %i\n", r_shadow_rendermode);
@@ -2382,16 +2396,16 @@ void R_Shadow_RenderLighting(int firstvertex, int numvertices, int numtriangles,
                {
                case R_SHADOW_RENDERMODE_VISIBLELIGHTING:
                        GL_DepthTest(!(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST) && !r_showdisabledepthtest.integer);
-                       R_Shadow_RenderLighting_VisibleLighting(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, vec3_origin, vec3_origin, rsurface.texture->basetexture, r_texture_black, r_texture_black, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, false, false);
+                       R_Shadow_RenderLighting_VisibleLighting(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase, vec3_origin, vec3_origin, rsurface.texture->basetexture, r_texture_black, r_texture_black, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, false, false);
                        break;
                case R_SHADOW_RENDERMODE_LIGHT_GLSL:
-                       R_Shadow_RenderLighting_Light_GLSL(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, vec3_origin, vec3_origin, rsurface.texture->basetexture, r_texture_black, r_texture_black, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, false, false);
+                       R_Shadow_RenderLighting_Light_GLSL(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase, vec3_origin, vec3_origin, rsurface.texture->basetexture, r_texture_black, r_texture_black, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, false, false);
                        break;
                case R_SHADOW_RENDERMODE_LIGHT_DOT3:
-                       R_Shadow_RenderLighting_Light_Dot3(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, vec3_origin, vec3_origin, rsurface.texture->basetexture, r_texture_black, r_texture_black, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, false, false);
+                       R_Shadow_RenderLighting_Light_Dot3(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase, vec3_origin, vec3_origin, rsurface.texture->basetexture, r_texture_black, r_texture_black, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, false, false);
                        break;
                case R_SHADOW_RENDERMODE_LIGHT_VERTEX:
-                       R_Shadow_RenderLighting_Light_Vertex(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, vec3_origin, vec3_origin, rsurface.texture->basetexture, r_texture_black, r_texture_black, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, false, false);
+                       R_Shadow_RenderLighting_Light_Vertex(firstvertex, numvertices, numtriangles, element3i + firsttriangle * 3, lightcolorbase, vec3_origin, vec3_origin, rsurface.texture->basetexture, r_texture_black, r_texture_black, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, false, false);
                        break;
                default:
                        Con_Printf("R_Shadow_RenderLighting: unknown r_shadow_rendermode %i\n", r_shadow_rendermode);
@@ -2448,8 +2462,8 @@ void R_RTLight_Compile(rtlight_t *rtlight)
        int i;
        int numsurfaces, numleafs, numleafpvsbytes, numshadowtrispvsbytes, numlighttrispvsbytes;
        int lighttris, shadowtris, shadowmeshes, shadowmeshtris;
-       entity_render_t *ent = r_refdef.worldentity;
-       model_t *model = r_refdef.worldmodel;
+       entity_render_t *ent = r_refdef.scene.worldentity;
+       dp_model_t *model = r_refdef.scene.worldmodel;
        unsigned char *data;
 
        // compile the light
@@ -2472,7 +2486,7 @@ void R_RTLight_Compile(rtlight_t *rtlight)
                // this variable must be set for the CompileShadowVolume code
                r_shadow_compilingrtlight = rtlight;
                R_Shadow_EnlargeLeafSurfaceTrisBuffer(model->brush.num_leafs, model->num_surfaces, model->brush.shadowmesh ? model->brush.shadowmesh->numtriangles : model->surfmesh.num_triangles, model->surfmesh.num_triangles);
-               model->GetLightInfo(ent, rtlight->shadoworigin, rtlight->radius, rtlight->cullmins, rtlight->cullmaxs, r_shadow_buffer_leaflist, r_shadow_buffer_leafpvs, &numleafs, r_shadow_buffer_surfacelist, r_shadow_buffer_surfacepvs, &numsurfaces, r_shadow_buffer_shadowtrispvs, r_shadow_buffer_lighttrispvs);
+               model->GetLightInfo(ent, rtlight->shadoworigin, rtlight->radius, rtlight->cullmins, rtlight->cullmaxs, r_shadow_buffer_leaflist, r_shadow_buffer_leafpvs, &numleafs, r_shadow_buffer_surfacelist, r_shadow_buffer_surfacepvs, &numsurfaces, r_shadow_buffer_shadowtrispvs, r_shadow_buffer_lighttrispvs, r_shadow_buffer_visitingleafpvs);
                numleafpvsbytes = (model->brush.num_leafs + 7) >> 3;
                numshadowtrispvsbytes = ((model->brush.shadowmesh ? model->brush.shadowmesh->numtriangles : model->surfmesh.num_triangles) + 7) >> 3;
                numlighttrispvsbytes = (model->surfmesh.num_triangles + 7) >> 3;
@@ -2564,9 +2578,10 @@ void R_Shadow_UncompileWorldLights(void)
 {
        size_t lightindex;
        dlight_t *light;
-       for (lightindex = 0;lightindex < Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray);lightindex++)
+       size_t range = Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray); // checked
+       for (lightindex = 0;lightindex < range;lightindex++)
        {
-               light = Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+               light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
                if (!light)
                        continue;
                R_RTLight_Uncompile(&light->rtlight);
@@ -2583,15 +2598,15 @@ void R_Shadow_ComputeShadowCasterCullingPlanes(rtlight_t *rtlight)
        rsurface.rtlight_numfrustumplanes = 0;
 
        // haven't implemented a culling path for ortho rendering
-       if (!r_view.useperspective)
+       if (!r_refdef.view.useperspective)
        {
                // check if the light is on screen and copy the 4 planes if it is
                for (i = 0;i < 4;i++)
-                       if (PlaneDiff(rtlight->shadoworigin, &r_view.frustum[i]) < -0.03125)
+                       if (PlaneDiff(rtlight->shadoworigin, &r_refdef.view.frustum[i]) < -0.03125)
                                break;
                if (i == 4)
                        for (i = 0;i < 4;i++)
-                               rsurface.rtlight_frustumplanes[rsurface.rtlight_numfrustumplanes++] = r_view.frustum[i];
+                               rsurface.rtlight_frustumplanes[rsurface.rtlight_numfrustumplanes++] = r_refdef.view.frustum[i];
                return;
        }
 
@@ -2610,10 +2625,10 @@ void R_Shadow_ComputeShadowCasterCullingPlanes(rtlight_t *rtlight)
        {
                // quickly reject standard frustum planes that put the light
                // origin outside the frustum
-               if (PlaneDiff(rtlight->shadoworigin, &r_view.frustum[i]) < -0.03125)
+               if (PlaneDiff(rtlight->shadoworigin, &r_refdef.view.frustum[i]) < -0.03125)
                        continue;
                // copy the plane
-               rsurface.rtlight_frustumplanes[rsurface.rtlight_numfrustumplanes++] = r_view.frustum[i];
+               rsurface.rtlight_frustumplanes[rsurface.rtlight_numfrustumplanes++] = r_refdef.view.frustum[i];
        }
        // if all the standard frustum planes were accepted, the light is onscreen
        // otherwise we need to generate some more planes below...
@@ -2625,12 +2640,12 @@ void R_Shadow_ComputeShadowCasterCullingPlanes(rtlight_t *rtlight)
                {
                        // create a plane using the view origin and light origin, and a
                        // single point from the frustum corner set
-                       TriangleNormal(r_view.origin, r_view.frustumcorner[i], rtlight->shadoworigin, plane.normal);
+                       TriangleNormal(r_refdef.view.origin, r_refdef.view.frustumcorner[i], rtlight->shadoworigin, plane.normal);
                        VectorNormalize(plane.normal);
-                       plane.dist = DotProduct(r_view.origin, plane.normal);
+                       plane.dist = DotProduct(r_refdef.view.origin, plane.normal);
                        // see if this plane is backwards and flip it if so
                        for (j = 0;j < 4;j++)
-                               if (j != i && DotProduct(r_view.frustumcorner[j], plane.normal) - plane.dist < -0.03125)
+                               if (j != i && DotProduct(r_refdef.view.frustumcorner[j], plane.normal) - plane.dist < -0.03125)
                                        break;
                        if (j < 4)
                        {
@@ -2638,7 +2653,7 @@ void R_Shadow_ComputeShadowCasterCullingPlanes(rtlight_t *rtlight)
                                plane.dist *= -1;
                                // flipped plane, test again to see if it is now valid
                                for (j = 0;j < 4;j++)
-                                       if (j != i && DotProduct(r_view.frustumcorner[j], plane.normal) - plane.dist < -0.03125)
+                                       if (j != i && DotProduct(r_refdef.view.frustumcorner[j], plane.normal) - plane.dist < -0.03125)
                                                break;
                                // if the plane is still not valid, then it is dividing the
                                // frustum and has to be rejected
@@ -2664,7 +2679,7 @@ void R_Shadow_ComputeShadowCasterCullingPlanes(rtlight_t *rtlight)
        for (i = 0;i < rsurface.rtlight_numfrustumplanes;i++)
        {
                plane = rsurface.rtlight_frustumplanes[i];
-               Con_Printf("light %p plane #%i %f %f %f : %f (%f %f %f %f %f)\n", rtlight, i, plane.normal[0], plane.normal[1], plane.normal[2], plane.dist, PlaneDiff(r_view.frustumcorner[0], &plane), PlaneDiff(r_view.frustumcorner[1], &plane), PlaneDiff(r_view.frustumcorner[2], &plane), PlaneDiff(r_view.frustumcorner[3], &plane), PlaneDiff(rtlight->shadoworigin, &plane));
+               Con_Printf("light %p plane #%i %f %f %f : %f (%f %f %f %f %f)\n", rtlight, i, plane.normal[0], plane.normal[1], plane.normal[2], plane.dist, PlaneDiff(r_refdef.view.frustumcorner[0], &plane), PlaneDiff(r_refdef.view.frustumcorner[1], &plane), PlaneDiff(r_refdef.view.frustumcorner[2], &plane), PlaneDiff(r_refdef.view.frustumcorner[3], &plane), PlaneDiff(rtlight->shadoworigin, &plane));
        }
 #endif
 
@@ -2754,35 +2769,35 @@ void R_Shadow_DrawWorldShadow(int numsurfaces, int *surfacelist, const unsigned
                        if (r_shadow_rendermode == R_SHADOW_RENDERMODE_STENCIL)
                        {
                                // decrement stencil if backface is behind depthbuffer
-                               GL_CullFace(r_view.cullface_front);
+                               GL_CullFace(r_refdef.view.cullface_front);
                                qglStencilOp(GL_KEEP, GL_DECR, GL_KEEP);CHECKGLERROR
-                               R_Mesh_Draw(0, mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->ebo, 0);
+                               R_Mesh_Draw(0, mesh->numverts, 0, mesh->numtriangles, mesh->element3i, mesh->element3s, mesh->ebo3i, mesh->ebo3s);
                                // increment stencil if frontface is behind depthbuffer
-                               GL_CullFace(r_view.cullface_back);
+                               GL_CullFace(r_refdef.view.cullface_back);
                                qglStencilOp(GL_KEEP, GL_INCR, GL_KEEP);CHECKGLERROR
                        }
-                       R_Mesh_Draw(0, mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->ebo, 0);
+                       R_Mesh_Draw(0, mesh->numverts, 0, mesh->numtriangles, mesh->element3i, mesh->element3s, mesh->ebo3i, mesh->ebo3s);
                        GL_LockArrays(0, 0);
                }
                CHECKGLERROR
        }
-       else if (numsurfaces && r_refdef.worldmodel->brush.shadowmesh && r_shadow_culltriangles.integer)
+       else if (numsurfaces && r_refdef.scene.worldmodel->brush.shadowmesh && r_shadow_culltriangles.integer)
        {
                int t, tend;
                int surfacelistindex;
                msurface_t *surface;
-               R_Shadow_PrepareShadowMark(r_refdef.worldmodel->brush.shadowmesh->numtriangles);
+               R_Shadow_PrepareShadowMark(r_refdef.scene.worldmodel->brush.shadowmesh->numtriangles);
                for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++)
                {
-                       surface = r_refdef.worldmodel->data_surfaces + surfacelist[surfacelistindex];
+                       surface = r_refdef.scene.worldmodel->data_surfaces + surfacelist[surfacelistindex];
                        for (t = surface->num_firstshadowmeshtriangle, tend = t + surface->num_triangles;t < tend;t++)
                                if (CHECKPVSBIT(trispvs, t))
                                        shadowmarklist[numshadowmark++] = t;
                }
-               R_Shadow_VolumeFromList(r_refdef.worldmodel->brush.shadowmesh->numverts, r_refdef.worldmodel->brush.shadowmesh->numtriangles, r_refdef.worldmodel->brush.shadowmesh->vertex3f, r_refdef.worldmodel->brush.shadowmesh->element3i, r_refdef.worldmodel->brush.shadowmesh->neighbor3i, rsurface.rtlight->shadoworigin, NULL, rsurface.rtlight->radius + r_refdef.worldmodel->radius*2 + r_shadow_projectdistance.value, numshadowmark, shadowmarklist);
+               R_Shadow_VolumeFromList(r_refdef.scene.worldmodel->brush.shadowmesh->numverts, r_refdef.scene.worldmodel->brush.shadowmesh->numtriangles, r_refdef.scene.worldmodel->brush.shadowmesh->vertex3f, r_refdef.scene.worldmodel->brush.shadowmesh->element3i, r_refdef.scene.worldmodel->brush.shadowmesh->neighbor3i, rsurface.rtlight->shadoworigin, NULL, rsurface.rtlight->radius + r_refdef.scene.worldmodel->radius*2 + r_shadow_projectdistance.value, numshadowmark, shadowmarklist, r_refdef.scene.worldmodel->normalmins, r_refdef.scene.worldmodel->normalmaxs);
        }
        else if (numsurfaces)
-               r_refdef.worldmodel->DrawShadowVolume(r_refdef.worldentity, rsurface.rtlight->shadoworigin, NULL, rsurface.rtlight->radius, numsurfaces, surfacelist, rsurface.rtlight_cullmins, rsurface.rtlight_cullmaxs);
+               r_refdef.scene.worldmodel->DrawShadowVolume(r_refdef.scene.worldentity, rsurface.rtlight->shadoworigin, NULL, rsurface.rtlight->radius, numsurfaces, surfacelist, rsurface.rtlight_cullmins, rsurface.rtlight_cullmaxs);
 }
 
 void R_Shadow_DrawEntityShadow(entity_render_t *ent)
@@ -2805,6 +2820,7 @@ void R_Shadow_SetupEntityLight(const entity_render_t *ent)
 {
        // set up properties for rendering light onto this entity
        RSurf_ActiveModelEntity(ent, true, true);
+       GL_AlphaTest(false);
        Matrix4x4_Concat(&rsurface.entitytolight, &rsurface.rtlight->matrix_worldtolight, &ent->matrix);
        Matrix4x4_Concat(&rsurface.entitytoattenuationxyz, &matrix_attenuationxyz, &rsurface.entitytolight);
        Matrix4x4_Concat(&rsurface.entitytoattenuationz, &matrix_attenuationz, &rsurface.entitytolight);
@@ -2815,11 +2831,12 @@ void R_Shadow_SetupEntityLight(const entity_render_t *ent)
 
 void R_Shadow_DrawWorldLight(int numsurfaces, int *surfacelist, const unsigned char *trispvs)
 {
-       if (!r_refdef.worldmodel->DrawLight)
+       if (!r_refdef.scene.worldmodel->DrawLight)
                return;
 
        // set up properties for rendering light onto this entity
        RSurf_ActiveWorldEntity();
+       GL_AlphaTest(false);
        rsurface.entitytolight = rsurface.rtlight->matrix_worldtolight;
        Matrix4x4_Concat(&rsurface.entitytoattenuationxyz, &matrix_attenuationxyz, &rsurface.entitytolight);
        Matrix4x4_Concat(&rsurface.entitytoattenuationz, &matrix_attenuationz, &rsurface.entitytolight);
@@ -2827,17 +2844,16 @@ void R_Shadow_DrawWorldLight(int numsurfaces, int *surfacelist, const unsigned c
        if (r_shadow_lightingrendermode == R_SHADOW_RENDERMODE_LIGHT_GLSL)
                R_Mesh_TexMatrix(3, &rsurface.entitytolight);
 
-       r_refdef.worldmodel->DrawLight(r_refdef.worldentity, numsurfaces, surfacelist, trispvs);
+       r_refdef.scene.worldmodel->DrawLight(r_refdef.scene.worldentity, numsurfaces, surfacelist, trispvs);
 }
 
 void R_Shadow_DrawEntityLight(entity_render_t *ent)
 {
-       model_t *model = ent->model;
+       dp_model_t *model = ent->model;
        if (!model->DrawLight)
                return;
 
        R_Shadow_SetupEntityLight(ent);
-       R_UpdateAllTextureInfo(ent);
 
        model->DrawLight(ent, model->nummodelsurfaces, model->surfacelist, NULL);
 }
@@ -2853,10 +2869,10 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible)
        int numlightentities_noselfshadow;
        int numshadowentities;
        int numshadowentities_noselfshadow;
-       entity_render_t *lightentities[MAX_EDICTS];
-       entity_render_t *lightentities_noselfshadow[MAX_EDICTS];
-       entity_render_t *shadowentities[MAX_EDICTS];
-       entity_render_t *shadowentities_noselfshadow[MAX_EDICTS];
+       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];
 
        // skip lights that don't light because of ambientscale+diffusescale+specularscale being 0 (corona only lights)
        // skip lights that are basically invisible (color 0 0 0)
@@ -2873,7 +2889,7 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible)
        rtlight->currentcubemap = rtlight->cubemapname[0] ? R_Shadow_Cubemap(rtlight->cubemapname) : r_texture_whitecube;
 
        // look up the light style value at this time
-       f = (rtlight->style >= 0 ? r_refdef.rtlightstylevalue[rtlight->style] : 1) * r_shadow_lightintensityscale.value;
+       f = (rtlight->style >= 0 ? r_refdef.scene.rtlightstylevalue[rtlight->style] : 1) * r_shadow_lightintensityscale.value;
        VectorScale(rtlight->color, f, rtlight->currentcolor);
        /*
        if (rtlight->selected)
@@ -2906,12 +2922,12 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible)
                shadowtrispvs = rtlight->static_shadowtrispvs;
                lighttrispvs = rtlight->static_lighttrispvs;
        }
-       else if (r_refdef.worldmodel && r_refdef.worldmodel->GetLightInfo)
+       else if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->GetLightInfo)
        {
                // dynamic light, world available and can receive realtime lighting
                // calculate lit surfaces and leafs
-               R_Shadow_EnlargeLeafSurfaceTrisBuffer(r_refdef.worldmodel->brush.num_leafs, r_refdef.worldmodel->num_surfaces, r_refdef.worldmodel->brush.shadowmesh ? r_refdef.worldmodel->brush.shadowmesh->numtriangles : r_refdef.worldmodel->surfmesh.num_triangles, r_refdef.worldmodel->surfmesh.num_triangles);
-               r_refdef.worldmodel->GetLightInfo(r_refdef.worldentity, rtlight->shadoworigin, rtlight->radius, rsurface.rtlight_cullmins, rsurface.rtlight_cullmaxs, r_shadow_buffer_leaflist, r_shadow_buffer_leafpvs, &numleafs, r_shadow_buffer_surfacelist, r_shadow_buffer_surfacepvs, &numsurfaces, r_shadow_buffer_shadowtrispvs, r_shadow_buffer_lighttrispvs);
+               R_Shadow_EnlargeLeafSurfaceTrisBuffer(r_refdef.scene.worldmodel->brush.num_leafs, r_refdef.scene.worldmodel->num_surfaces, r_refdef.scene.worldmodel->brush.shadowmesh ? r_refdef.scene.worldmodel->brush.shadowmesh->numtriangles : r_refdef.scene.worldmodel->surfmesh.num_triangles, r_refdef.scene.worldmodel->surfmesh.num_triangles);
+               r_refdef.scene.worldmodel->GetLightInfo(r_refdef.scene.worldentity, rtlight->shadoworigin, rtlight->radius, rsurface.rtlight_cullmins, rsurface.rtlight_cullmaxs, r_shadow_buffer_leaflist, r_shadow_buffer_leafpvs, &numleafs, r_shadow_buffer_surfacelist, r_shadow_buffer_surfacepvs, &numsurfaces, r_shadow_buffer_shadowtrispvs, r_shadow_buffer_lighttrispvs, r_shadow_buffer_visitingleafpvs);
                leaflist = r_shadow_buffer_leaflist;
                leafpvs = r_shadow_buffer_leafpvs;
                surfacelist = r_shadow_buffer_surfacelist;
@@ -2936,7 +2952,7 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible)
        if (numleafs)
        {
                for (i = 0;i < numleafs;i++)
-                       if (r_viewcache.world_leafvisible[leaflist[i]])
+                       if (r_refdef.viewcache.world_leafvisible[leaflist[i]])
                                break;
                if (i == numleafs)
                        return;
@@ -2955,10 +2971,10 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible)
        // add dynamic entities that are lit by the light
        if (r_drawentities.integer)
        {
-               for (i = 0;i < r_refdef.numentities;i++)
+               for (i = 0;i < r_refdef.scene.numentities;i++)
                {
-                       model_t *model;
-                       entity_render_t *ent = r_refdef.entities[i];
+                       dp_model_t *model;
+                       entity_render_t *ent = r_refdef.scene.entities[i];
                        vec3_t org;
                        if (!BoxesOverlap(ent->mins, ent->maxs, rsurface.rtlight_cullmins, rsurface.rtlight_cullmaxs))
                                continue;
@@ -2968,13 +2984,13 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible)
                                continue;
                        if (!(model = ent->model))
                                continue;
-                       if (r_viewcache.entityvisible[i] && model->DrawLight && (ent->flags & RENDER_LIGHT))
+                       if (r_refdef.viewcache.entityvisible[i] && model->DrawLight && (ent->flags & RENDER_LIGHT))
                        {
                                // this entity wants to receive light, is visible, and is
                                // inside the light box
                                // TODO: check if the surfaces in the model can receive light
                                // so now check if it's in a leaf seen by the light
-                               if (r_refdef.worldmodel && r_refdef.worldmodel->brush.BoxTouchingLeafPVS && !r_refdef.worldmodel->brush.BoxTouchingLeafPVS(r_refdef.worldmodel, leafpvs, ent->mins, ent->maxs))
+                               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;
@@ -3003,7 +3019,7 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible)
                                // cast a shadow...
                                // TODO: check if the surfaces in the model can cast shadow
                                // now check if it is in a leaf seen by the light
-                               if (r_refdef.worldmodel && r_refdef.worldmodel->brush.BoxTouchingLeafPVS && !r_refdef.worldmodel->brush.BoxTouchingLeafPVS(r_refdef.worldmodel, leafpvs, ent->mins, ent->maxs))
+                               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;
                                // about the VectorDistance2 - light emitting entities should not cast their own shadow
                                Matrix4x4_OriginFromMatrix(&ent->matrix, org);
@@ -3023,7 +3039,7 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible)
                return;
 
        // don't let sound skip if going slow
-       if (r_refdef.extraupdate)
+       if (r_refdef.scene.extraupdate)
                S_ExtraUpdate ();
 
        // make this the active rtlight for rendering purposes
@@ -3031,7 +3047,7 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible)
        // count this light in the r_speeds
        r_refdef.stats.lights++;
 
-       if (r_showshadowvolumes.integer && r_view.showdebug && numsurfaces + numshadowentities + numshadowentities_noselfshadow && rtlight->shadow && (rtlight->isstatic ? r_refdef.rtworldshadows : r_refdef.rtdlightshadows))
+       if (r_showshadowvolumes.integer && r_refdef.view.showdebug && numsurfaces + numshadowentities + numshadowentities_noselfshadow && rtlight->shadow && (rtlight->isstatic ? r_refdef.scene.rtworldshadows : r_refdef.scene.rtdlightshadows))
        {
                // optionally draw visible shape of the shadow volumes
                // for performance analysis by level designers
@@ -3044,11 +3060,12 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible)
                        R_Shadow_DrawEntityShadow(shadowentities_noselfshadow[i]);
        }
 
-       if (gl_stencil && numsurfaces + numshadowentities + numshadowentities_noselfshadow && rtlight->shadow && (rtlight->isstatic ? r_refdef.rtworldshadows : r_refdef.rtdlightshadows))
+       if (gl_stencil && numsurfaces + numshadowentities + numshadowentities_noselfshadow && rtlight->shadow && (rtlight->isstatic ? r_refdef.scene.rtworldshadows : r_refdef.scene.rtdlightshadows))
        {
                // draw stencil shadow volumes to mask off pixels that are in shadow
                // so that they won't receive lighting
-               R_Shadow_RenderMode_StencilShadowVolumes(true);
+               R_Shadow_ClearStencil();
+               R_Shadow_RenderMode_StencilShadowVolumes();
                if (numsurfaces)
                        R_Shadow_DrawWorldShadow(numsurfaces, surfacelist, shadowtrispvs);
                for (i = 0;i < numshadowentities;i++)
@@ -3062,14 +3079,14 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible)
 
                        // optionally draw the illuminated areas
                        // for performance analysis by level designers
-                       if (r_showlighting.integer && r_view.showdebug)
+                       if (r_showlighting.integer && r_refdef.view.showdebug)
                        {
                                R_Shadow_RenderMode_VisibleLighting(!r_showdisabledepthtest.integer, false);
                                for (i = 0;i < numlightentities_noselfshadow;i++)
                                        R_Shadow_DrawEntityLight(lightentities_noselfshadow[i]);
                        }
 
-                       R_Shadow_RenderMode_StencilShadowVolumes(false);
+                       R_Shadow_RenderMode_StencilShadowVolumes();
                }
                for (i = 0;i < numshadowentities_noselfshadow;i++)
                        R_Shadow_DrawEntityShadow(shadowentities_noselfshadow[i]);
@@ -3085,7 +3102,7 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible)
 
                        // optionally draw the illuminated areas
                        // for performance analysis by level designers
-                       if (r_showlighting.integer && r_view.showdebug)
+                       if (r_showlighting.integer && r_refdef.view.showdebug)
                        {
                                R_Shadow_RenderMode_VisibleLighting(!r_showdisabledepthtest.integer, false);
                                if (numsurfaces)
@@ -3110,7 +3127,7 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible)
 
                        // optionally draw the illuminated areas
                        // for performance analysis by level designers
-                       if (r_showlighting.integer && r_view.showdebug)
+                       if (r_showlighting.integer && r_refdef.view.showdebug)
                        {
                                R_Shadow_RenderMode_VisibleLighting(false, false);
                                if (numsurfaces)
@@ -3131,40 +3148,40 @@ void R_ShadowVolumeLighting(qboolean visible)
        int lnum;
        size_t lightindex;
        dlight_t *light;
-
-       if (r_refdef.worldmodel && strncmp(r_refdef.worldmodel->name, r_shadow_mapname, sizeof(r_shadow_mapname)))
-               R_Shadow_EditLights_Reload_f();
+       size_t range;
 
        if (r_editlights.integer)
                R_Shadow_DrawLightSprites();
 
        R_Shadow_RenderMode_Begin();
 
-       flag = r_refdef.rtworld ? LIGHTFLAG_REALTIMEMODE : LIGHTFLAG_NORMALMODE;
+       flag = r_refdef.scene.rtworld ? LIGHTFLAG_REALTIMEMODE : LIGHTFLAG_NORMALMODE;
        if (r_shadow_debuglight.integer >= 0)
        {
                lightindex = r_shadow_debuglight.integer;
-               light = Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+               light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
                if (light && (light->flags & flag))
                        R_DrawRTLight(&light->rtlight, visible);
        }
        else
        {
-               for (lightindex = 0;lightindex < Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray);lightindex++)
+               range = Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray); // checked
+               for (lightindex = 0;lightindex < range;lightindex++)
                {
-                       light = Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+                       light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
                        if (light && (light->flags & flag))
                                R_DrawRTLight(&light->rtlight, visible);
                }
        }
-       if (r_refdef.rtdlight)
-               for (lnum = 0;lnum < r_refdef.numlights;lnum++)
-                       R_DrawRTLight(&r_refdef.lights[lnum], visible);
+       if (r_refdef.scene.rtdlight)
+               for (lnum = 0;lnum < r_refdef.scene.numlights;lnum++)
+                       R_DrawRTLight(&r_refdef.scene.lights[lnum], visible);
 
        R_Shadow_RenderMode_End();
 }
 
-extern void R_SetupView(void);
+extern void R_SetupView(qboolean allowwaterclippingplane);
+extern cvar_t r_shadows;
 extern cvar_t r_shadows_throwdistance;
 void R_DrawModelShadows(void)
 {
@@ -3174,13 +3191,14 @@ void R_DrawModelShadows(void)
        vec3_t relativelightorigin;
        vec3_t relativelightdirection;
        vec3_t relativeshadowmins, relativeshadowmaxs;
+       vec3_t tmp;
        float vertex3f[12];
 
        if (!r_drawentities.integer || !gl_stencil)
                return;
 
        CHECKGLERROR
-       GL_Scissor(r_view.x, r_view.y, r_view.width, r_view.height);
+       GL_Scissor(r_refdef.view.x, r_refdef.view.y, r_refdef.view.width, r_refdef.view.height);
 
        r_shadow_rendermode = R_SHADOW_RENDERMODE_NONE;
 
@@ -3191,18 +3209,54 @@ void R_DrawModelShadows(void)
        else
                r_shadow_shadowingrendermode = R_SHADOW_RENDERMODE_STENCIL;
 
-       R_Shadow_RenderMode_StencilShadowVolumes(true);
+       R_Shadow_ClearStencil();
+       R_Shadow_RenderMode_StencilShadowVolumes();
 
-       for (i = 0;i < r_refdef.numentities;i++)
+       for (i = 0;i < r_refdef.scene.numentities;i++)
        {
-               ent = r_refdef.entities[i];
+               ent = r_refdef.scene.entities[i];
                // cast shadows from anything that is not a submodel of the map
                if (ent->model && ent->model->DrawShadowVolume != NULL && !ent->model->brush.submodel && (ent->flags & RENDER_SHADOW))
                {
                        relativethrowdistance = r_shadows_throwdistance.value * Matrix4x4_ScaleFromMatrix(&ent->inversematrix);
                        VectorSet(relativeshadowmins, -relativethrowdistance, -relativethrowdistance, -relativethrowdistance);
                        VectorSet(relativeshadowmaxs, relativethrowdistance, relativethrowdistance, relativethrowdistance);
-                       VectorNegate(ent->modellight_lightdir, relativelightdirection);
+
+                       if(r_shadows.integer == 2)
+                       {
+                               // 2: simpler mode, throw shadows always DOWN
+                               VectorSet(tmp, 0, 0, -1);
+                               Matrix4x4_Transform3x3(&ent->inversematrix, tmp, relativelightdirection);
+                       }
+                       else
+                       {
+                               if(ent->entitynumber != 0)
+                               {
+                                       // networked entity - might be attached in some way (then we should use the parent's light direction, to not tear apart attached entities)
+                                       int entnum, entnum2, recursion;
+                                       entnum = entnum2 = ent->entitynumber;
+                                       for(recursion = 32; recursion > 0; --recursion)
+                                       {
+                                               entnum2 = cl.entities[entnum].state_current.tagentity;
+                                               if(entnum2 >= 1 && entnum2 < cl.num_entities && cl.entities_active[entnum2])
+                                                       entnum = entnum2;
+                                               else
+                                                       break;
+                                       }
+                                       if(recursion && recursion != 32) // if we followed a valid non-empty attachment chain
+                                       {
+                                               VectorNegate(cl.entities[entnum].render.modellight_lightdir, relativelightdirection);
+                                               // transform into modelspace of OUR entity
+                                               Matrix4x4_Transform3x3(&cl.entities[entnum].render.matrix, relativelightdirection, tmp);
+                                               Matrix4x4_Transform3x3(&ent->inversematrix, tmp, relativelightdirection);
+                                       }
+                                       else
+                                               VectorNegate(ent->modellight_lightdir, relativelightdirection);
+                               }
+                               else
+                                       VectorNegate(ent->modellight_lightdir, relativelightdirection);
+                       }
+
                        VectorScale(relativelightdirection, -relativethrowdistance, relativelightorigin);
                        RSurf_ActiveModelEntity(ent, false, false);
                        ent->model->DrawShadowVolume(ent, relativelightorigin, relativelightdirection, relativethrowdistance, ent->model->nummodelsurfaces, ent->model->surfacelist, relativeshadowmins, relativeshadowmaxs);
@@ -3220,8 +3274,8 @@ void R_DrawModelShadows(void)
 
        // set up ortho view for rendering this pass
        GL_SetupView_Mode_Ortho(0, 0, 1, 1, -10, 100);
-       GL_Scissor(r_view.x, r_view.y, r_view.width, r_view.height);
-       GL_ColorMask(r_view.colormask[0], r_view.colormask[1], r_view.colormask[2], 1);
+       GL_Scissor(r_refdef.view.x, r_refdef.view.y, r_refdef.view.width, r_refdef.view.height);
+       GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1);
        GL_ScissorTest(true);
        R_Mesh_Matrix(&identitymatrix);
        R_Mesh_ResetTextureState();
@@ -3235,7 +3289,7 @@ void R_DrawModelShadows(void)
        GL_DepthMask(false);
        GL_PolygonOffset(0, 0);CHECKGLERROR
        GL_Color(0, 0, 0, 0.5);
-       GL_ColorMask(r_view.colormask[0], r_view.colormask[1], r_view.colormask[2], 1);
+       GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1);
        qglDepthFunc(GL_ALWAYS);CHECKGLERROR
        qglEnable(GL_STENCIL_TEST);CHECKGLERROR
        qglStencilMask(~0);CHECKGLERROR
@@ -3243,71 +3297,154 @@ void R_DrawModelShadows(void)
        qglStencilFunc(GL_NOTEQUAL, 128, ~0);CHECKGLERROR
 
        // apply the blend to the shadowed areas
-       R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
+       R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0);
 
        // restoring the perspective view is done by R_RenderScene
-       //R_SetupView();
+       //R_SetupView(true);
 
        // restore other state to normal
        R_Shadow_RenderMode_End();
 }
 
+void R_BeginCoronaQuery(rtlight_t *rtlight, float scale, qboolean usequery)
+{
+       // if it's too close, skip it
+       if (VectorLength(rtlight->color) < (1.0f / 256.0f))
+               return;
+       if (VectorDistance2(rtlight->shadoworigin, r_refdef.view.origin) < 32.0f * 32.0f)
+               return;
+       if (usequery && r_numqueries + 2 <= r_maxqueries)
+       {
+               rtlight->corona_queryindex_allpixels = r_queries[r_numqueries++];
+               rtlight->corona_queryindex_visiblepixels = r_queries[r_numqueries++];
+               CHECKGLERROR
+               qglBeginQueryARB(GL_SAMPLES_PASSED_ARB, rtlight->corona_queryindex_allpixels);
+               R_DrawSprite(GL_ONE, GL_ZERO, r_shadow_lightcorona, NULL, true, false, rtlight->shadoworigin, r_refdef.view.right, r_refdef.view.up, scale, -scale, -scale, scale, 1, 1, 1, 1);
+               qglEndQueryARB(GL_SAMPLES_PASSED_ARB);
+               qglBeginQueryARB(GL_SAMPLES_PASSED_ARB, rtlight->corona_queryindex_visiblepixels);
+               R_DrawSprite(GL_ONE, GL_ZERO, r_shadow_lightcorona, NULL, false, false, rtlight->shadoworigin, r_refdef.view.right, r_refdef.view.up, scale, -scale, -scale, scale, 1, 1, 1, 1);
+               qglEndQueryARB(GL_SAMPLES_PASSED_ARB);
+               CHECKGLERROR
+       }
+       rtlight->corona_visibility = 1;
+}
+
+void R_DrawCorona(rtlight_t *rtlight, float cscale, float scale)
+{
+       vec3_t color;
+       GLint allpixels = 0, visiblepixels = 0;
+       // now we have to check the query result
+       if (rtlight->corona_queryindex_visiblepixels)
+       {
+               CHECKGLERROR
+               qglGetQueryObjectivARB(rtlight->corona_queryindex_visiblepixels, GL_QUERY_RESULT_ARB, &visiblepixels);
+               qglGetQueryObjectivARB(rtlight->corona_queryindex_allpixels, GL_QUERY_RESULT_ARB, &allpixels);
+               CHECKGLERROR
+               //Con_Printf("%i of %i pixels\n", (int)visiblepixels, (int)allpixels);
+               if (visiblepixels < 1 || allpixels < 1)
+                       return;
+               rtlight->corona_visibility *= (float)visiblepixels / (float)allpixels;
+               cscale *= rtlight->corona_visibility;
+       }
+       else
+       {
+               // FIXME: these traces should scan all render entities instead of cl.world
+               if (CL_Move(r_refdef.view.origin, vec3_origin, vec3_origin, rtlight->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction < 1)
+                       return;
+       }
+       VectorScale(rtlight->color, cscale, color);
+       if (VectorLength(color) > (1.0f / 256.0f))
+               R_DrawSprite(GL_ONE, GL_ONE, r_shadow_lightcorona, NULL, true, false, rtlight->shadoworigin, r_refdef.view.right, r_refdef.view.up, scale, -scale, -scale, scale, color[0], color[1], color[2], 1);
+}
+
 void R_DrawCoronas(void)
 {
        int i, flag;
-       float cscale, scale;
+       qboolean usequery;
        size_t lightindex;
        dlight_t *light;
        rtlight_t *rtlight;
+       size_t range;
        if (r_coronas.value < (1.0f / 256.0f) && !gl_flashblend.integer)
                return;
+       if (r_waterstate.renderingscene)
+               return;
+       flag = r_refdef.scene.rtworld ? LIGHTFLAG_REALTIMEMODE : LIGHTFLAG_NORMALMODE;
        R_Mesh_Matrix(&identitymatrix);
-       flag = r_refdef.rtworld ? LIGHTFLAG_REALTIMEMODE : LIGHTFLAG_NORMALMODE;
-       // FIXME: these traces should scan all render entities instead of cl.world
-       for (lightindex = 0;lightindex < Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray);lightindex++)
+
+       range = Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray); // checked
+
+       // check occlusion of coronas
+       // use GL_ARB_occlusion_query if available
+       // otherwise use raytraces
+       r_numqueries = 0;
+       usequery = gl_support_arb_occlusion_query && r_coronas_occlusionquery.integer;
+       if (usequery)
        {
-               light = Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+               GL_ColorMask(0,0,0,0);
+               if (r_maxqueries < range + r_refdef.scene.numlights)
+               if (r_maxqueries < R_MAX_OCCLUSION_QUERIES)
+               {
+                       i = r_maxqueries;
+                       r_maxqueries = (range + r_refdef.scene.numlights) * 2;
+                       r_maxqueries = min(r_maxqueries, R_MAX_OCCLUSION_QUERIES);
+                       CHECKGLERROR
+                       qglGenQueriesARB(r_maxqueries - i, r_queries + i);
+                       CHECKGLERROR
+               }
+       }
+       for (lightindex = 0;lightindex < range;lightindex++)
+       {
+               light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
                if (!light)
                        continue;
                rtlight = &light->rtlight;
+               rtlight->corona_visibility = 0;
+               rtlight->corona_queryindex_visiblepixels = 0;
+               rtlight->corona_queryindex_allpixels = 0;
                if (!(rtlight->flags & flag))
                        continue;
-               if (rtlight->corona * r_coronas.value <= 0)
+               if (rtlight->corona <= 0)
                        continue;
                if (r_shadow_debuglight.integer >= 0 && r_shadow_debuglight.integer != (int)lightindex)
                        continue;
-               cscale = rtlight->corona * r_coronas.value* 0.25f;
-               scale = rtlight->radius * rtlight->coronasizescale;
-               if (VectorDistance2(rtlight->shadoworigin, r_view.origin) < 16.0f * 16.0f)
-                       continue;
-               if (CL_Move(r_view.origin, vec3_origin, vec3_origin, rtlight->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction < 1)
-                       continue;
-               R_DrawSprite(GL_ONE, GL_ONE, r_shadow_lightcorona, NULL, true, false, rtlight->shadoworigin, r_view.right, r_view.up, scale, -scale, -scale, scale, rtlight->color[0] * cscale, rtlight->color[1] * cscale, rtlight->color[2] * cscale, 1);
+               R_BeginCoronaQuery(rtlight, rtlight->radius * rtlight->coronasizescale * r_coronas_occlusionsizescale.value, usequery);
        }
-       for (i = 0;i < r_refdef.numlights;i++)
+       for (i = 0;i < r_refdef.scene.numlights;i++)
        {
-               rtlight = &r_refdef.lights[i];
+               rtlight = &r_refdef.scene.lights[i];
+               rtlight->corona_visibility = 0;
+               rtlight->corona_queryindex_visiblepixels = 0;
+               rtlight->corona_queryindex_allpixels = 0;
                if (!(rtlight->flags & flag))
                        continue;
                if (rtlight->corona <= 0)
                        continue;
-               if (VectorDistance2(rtlight->shadoworigin, r_view.origin) < 32.0f * 32.0f)
+               R_BeginCoronaQuery(rtlight, rtlight->radius * rtlight->coronasizescale * r_coronas_occlusionsizescale.value, usequery);
+       }
+       if (usequery)
+               GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1);
+
+       // now draw the coronas using the query data for intensity info
+       for (lightindex = 0;lightindex < range;lightindex++)
+       {
+               light = Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+               if (!light)
                        continue;
-               if (gl_flashblend.integer)
-               {
-                       cscale = rtlight->corona * 1.0f;
-                       scale = rtlight->radius * rtlight->coronasizescale * 2.0f;
-               }
-               else
-               {
-                       cscale = rtlight->corona * r_coronas.value* 0.25f;
-                       scale = rtlight->radius * rtlight->coronasizescale;
-               }
-               if (VectorLength(rtlight->color) * cscale < (1.0f / 256.0f))
+               rtlight = &light->rtlight;
+               if (rtlight->corona_visibility <= 0)
                        continue;
-               if (CL_Move(r_view.origin, vec3_origin, vec3_origin, rtlight->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction < 1)
+               R_DrawCorona(rtlight, rtlight->corona * r_coronas.value * 0.25f, rtlight->radius * rtlight->coronasizescale);
+       }
+       for (i = 0;i < r_refdef.scene.numlights;i++)
+       {
+               rtlight = &r_refdef.scene.lights[i];
+               if (rtlight->corona_visibility <= 0)
                        continue;
-               R_DrawSprite(GL_ONE, GL_ONE, r_shadow_lightcorona, NULL, true, false, rtlight->shadoworigin, r_view.right, r_view.up, scale, -scale, -scale, scale, rtlight->color[0] * cscale, rtlight->color[1] * cscale, rtlight->color[2] * cscale, 1);
+               if (gl_flashblend.integer)
+                       R_DrawCorona(rtlight, rtlight->corona, rtlight->radius * rtlight->coronasizescale * 2.0f);
+               else
+                       R_DrawCorona(rtlight, rtlight->corona * r_coronas.value * 0.25f, rtlight->radius * rtlight->coronasizescale);
        }
 }
 
@@ -3395,6 +3532,9 @@ rtexture_t *R_Shadow_LoadCubemap(const char *basename)
        // if a cubemap loaded, upload it
        if (cubemappixels)
        {
+               if (developer_loading.integer)
+                       Con_Printf("loading cubemap \"%s\"\n", basename);
+
                if (!r_shadow_filters_texturepool)
                        r_shadow_filters_texturepool = R_AllocTexturePool();
                cubemaptexture = R_LoadTextureCubeMap(r_shadow_filters_texturepool, basename, cubemapsize, cubemappixels, TEXTYPE_BGRA, TEXF_PRECACHE | (gl_texturecompression_lightcubemaps.integer ? TEXF_COMPRESS : 0), NULL);
@@ -3402,11 +3542,15 @@ rtexture_t *R_Shadow_LoadCubemap(const char *basename)
        }
        else
        {
-               Con_Printf("Failed to load Cubemap \"%s\", tried ", basename);
-               for (j = 0;j < 3;j++)
-                       for (i = 0;i < 6;i++)
-                               Con_Printf("%s\"%s%s.tga\"", j + i > 0 ? ", " : "", basename, suffix[j][i].suffix);
-               Con_Print(" and was unable to find any of them.\n");
+               Con_DPrintf("failed to load cubemap \"%s\"\n", basename);
+               if (developer_loading.integer)
+               {
+                       Con_Printf("(tried tried images ");
+                       for (j = 0;j < 3;j++)
+                               for (i = 0;i < 6;i++)
+                                       Con_Printf("%s\"%s%s.tga\"", j + i > 0 ? ", " : "", basename, suffix[j][i].suffix);
+                       Con_Print(" and was unable to find any of them).\n");
+               }
        }
        return cubemaptexture;
 }
@@ -3416,19 +3560,26 @@ rtexture_t *R_Shadow_Cubemap(const char *basename)
        int i;
        for (i = 0;i < numcubemaps;i++)
                if (!strcasecmp(cubemaps[i].basename, basename))
-                       return cubemaps[i].texture;
+                       return cubemaps[i].texture ? cubemaps[i].texture : r_texture_whitecube;
        if (i >= MAX_CUBEMAPS)
                return r_texture_whitecube;
        numcubemaps++;
        strlcpy(cubemaps[i].basename, basename, sizeof(cubemaps[i].basename));
        cubemaps[i].texture = R_Shadow_LoadCubemap(cubemaps[i].basename);
-       if (!cubemaps[i].texture)
-               cubemaps[i].texture = r_texture_whitecube;
        return cubemaps[i].texture;
 }
 
 void R_Shadow_FreeCubemaps(void)
 {
+       int i;
+       for (i = 0;i < numcubemaps;i++)
+       {
+               if (developer_loading.integer)
+                       Con_Printf("unloading cubemap \"%s\"\n", cubemaps[i].basename);
+               if (cubemaps[i].texture)
+                       R_FreeTexture(cubemaps[i].texture);
+       }
+
        numcubemaps = 0;
        R_FreeTexturePool(&r_shadow_filters_texturepool);
 }
@@ -3486,9 +3637,10 @@ void R_Shadow_ClearWorldLights(void)
 {
        size_t lightindex;
        dlight_t *light;
-       for (lightindex = 0;lightindex < Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray);lightindex++)
+       size_t range = Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray); // checked
+       for (lightindex = 0;lightindex < range;lightindex++)
        {
-               light = Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+               light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
                if (light)
                        R_Shadow_FreeWorldLight(light);
        }
@@ -3508,7 +3660,7 @@ void R_Shadow_SelectLight(dlight_t *light)
 void R_Shadow_DrawCursor_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
 {
        // this is never batched (there can be only one)
-       R_DrawSprite(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, r_editlights_sprcursor->tex, r_editlights_sprcursor->tex, false, false, r_editlights_cursorlocation, r_view.right, r_view.up, EDLIGHTSPRSIZE, -EDLIGHTSPRSIZE, -EDLIGHTSPRSIZE, EDLIGHTSPRSIZE, 1, 1, 1, 1);
+       R_DrawSprite(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, r_editlights_sprcursor->tex, r_editlights_sprcursor->tex, false, false, r_editlights_cursorlocation, r_refdef.view.right, r_refdef.view.up, EDLIGHTSPRSIZE, -EDLIGHTSPRSIZE, -EDLIGHTSPRSIZE, EDLIGHTSPRSIZE, 1, 1, 1, 1);
 }
 
 void R_Shadow_DrawLightSprite_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
@@ -3538,10 +3690,10 @@ void R_Shadow_DrawLightSprite_TransparentCallback(const entity_render_t *ent, co
                pic = r_editlights_sprnoshadowlight;
        else
                pic = r_editlights_sprlight;
-       R_DrawSprite(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, pic->tex, pic->tex, false, false, light->origin, r_view.right, r_view.up, s, -s, -s, s, spritecolor[0], spritecolor[1], spritecolor[2], 1);
+       R_DrawSprite(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, pic->tex, pic->tex, false, false, light->origin, r_refdef.view.right, r_refdef.view.up, s, -s, -s, s, spritecolor[0], spritecolor[1], spritecolor[2], 1);
        // draw selection sprite if light is selected
        if (light->selected)
-               R_DrawSprite(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, r_editlights_sprselection->tex, r_editlights_sprselection->tex, false, false, light->origin, r_view.right, r_view.up, s, -s, -s, s, 1, 1, 1, 1);
+               R_DrawSprite(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, r_editlights_sprselection->tex, r_editlights_sprselection->tex, false, false, light->origin, r_refdef.view.right, r_refdef.view.up, s, -s, -s, s, 1, 1, 1, 1);
        // VorteX todo: add normalmode/realtime mode light overlay sprites?
 }
 
@@ -3549,9 +3701,10 @@ void R_Shadow_DrawLightSprites(void)
 {
        size_t lightindex;
        dlight_t *light;
-       for (lightindex = 0;lightindex < Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray);lightindex++)
+       size_t range = Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray); // checked
+       for (lightindex = 0;lightindex < range;lightindex++)
        {
-               light = Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+               light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
                if (light)
                        R_MeshQueue_AddTransparent(light->origin, R_Shadow_DrawLightSprite_TransparentCallback, (entity_render_t *)light, 5, &light->rtlight);
        }
@@ -3564,19 +3717,20 @@ void R_Shadow_SelectLightInView(void)
        dlight_t *best;
        size_t lightindex;
        dlight_t *light;
+       size_t range = Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray); // checked
        best = NULL;
        bestrating = 0;
-       for (lightindex = 0;lightindex < Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray);lightindex++)
+       for (lightindex = 0;lightindex < range;lightindex++)
        {
-               light = Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+               light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
                if (!light)
                        continue;
-               VectorSubtract(light->origin, r_view.origin, temp);
-               rating = (DotProduct(temp, r_view.forward) / sqrt(DotProduct(temp, temp)));
+               VectorSubtract(light->origin, r_refdef.view.origin, temp);
+               rating = (DotProduct(temp, r_refdef.view.forward) / sqrt(DotProduct(temp, temp)));
                if (rating >= 0.95)
                {
                        rating /= (1 + 0.0625f * sqrt(DotProduct(temp, temp)));
-                       if (bestrating < rating && CL_Move(light->origin, vec3_origin, vec3_origin, r_view.origin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction == 1.0f)
+                       if (bestrating < rating && CL_Move(light->origin, vec3_origin, vec3_origin, r_refdef.view.origin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction == 1.0f)
                        {
                                bestrating = rating;
                                best = light;
@@ -3591,12 +3745,12 @@ void R_Shadow_LoadWorldLights(void)
        int n, a, style, shadow, flags;
        char tempchar, *lightsstring, *s, *t, name[MAX_QPATH], cubemapname[MAX_QPATH];
        float origin[3], radius, color[3], angles[3], corona, coronasizescale, ambientscale, diffusescale, specularscale;
-       if (r_refdef.worldmodel == NULL)
+       if (cl.worldmodel == NULL)
        {
                Con_Print("No map loaded.\n");
                return;
        }
-       FS_StripExtension (r_refdef.worldmodel->name, name, sizeof (name));
+       FS_StripExtension (cl.worldmodel->name, name, sizeof (name));
        strlcat (name, ".rtlights", sizeof (name));
        lightsstring = (char *)FS_LoadFile(name, tempmempool, false, NULL);
        if (lightsstring)
@@ -3635,7 +3789,18 @@ void R_Shadow_LoadWorldLights(void)
                                t++;
                        }
                        *s = 0;
-                       a = sscanf(t, "%f %f %f %f %f %f %f %d %s %f %f %f %f %f %f %f %f %i", &origin[0], &origin[1], &origin[2], &radius, &color[0], &color[1], &color[2], &style, cubemapname, &corona, &angles[0], &angles[1], &angles[2], &coronasizescale, &ambientscale, &diffusescale, &specularscale, &flags);
+#if _MSC_VER >= 1400
+#define sscanf sscanf_s
+#endif
+                       cubemapname[sizeof(cubemapname)-1] = 0;
+#if MAX_QPATH != 128
+#error update this code if MAX_QPATH changes
+#endif
+                       a = sscanf(t, "%f %f %f %f %f %f %f %d %127s %f %f %f %f %f %f %f %f %i", &origin[0], &origin[1], &origin[2], &radius, &color[0], &color[1], &color[2], &style, cubemapname
+#if _MSC_VER >= 1400
+, sizeof(cubemapname)
+#endif
+, &corona, &angles[0], &angles[1], &angles[2], &coronasizescale, &ambientscale, &diffusescale, &specularscale, &flags);
                        *s = tempchar;
                        if (a < 18)
                                flags = LIGHTFLAG_REALTIMEMODE;
@@ -3687,28 +3852,30 @@ void R_Shadow_SaveWorldLights(void)
        char *buf, *oldbuf;
        char name[MAX_QPATH];
        char line[MAX_INPUTLINE];
-       if (!Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray))
+       size_t range = Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray); // checked, assuming the dpsnprintf mess doesn't screw it up...
+       // I hate lines which are 3 times my screen size :( --blub
+       if (!range)
                return;
-       if (r_refdef.worldmodel == NULL)
+       if (cl.worldmodel == NULL)
        {
                Con_Print("No map loaded.\n");
                return;
        }
-       FS_StripExtension (r_refdef.worldmodel->name, name, sizeof (name));
+       FS_StripExtension (cl.worldmodel->name, name, sizeof (name));
        strlcat (name, ".rtlights", sizeof (name));
        bufchars = bufmaxchars = 0;
        buf = NULL;
-       for (lightindex = 0;lightindex < Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray);lightindex++)
+       for (lightindex = 0;lightindex < range;lightindex++)
        {
-               light = Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+               light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
                if (!light)
                        continue;
                if (light->coronasizescale != 0.25f || light->ambientscale != 0 || light->diffusescale != 1 || light->specularscale != 1 || light->flags != LIGHTFLAG_REALTIMEMODE)
-                       sprintf(line, "%s%f %f %f %f %f %f %f %d \"%s\" %f %f %f %f %f %f %f %f %i\n", light->shadow ? "" : "!", light->origin[0], light->origin[1], light->origin[2], light->radius, light->color[0], light->color[1], light->color[2], light->style, light->cubemapname, light->corona, light->angles[0], light->angles[1], light->angles[2], light->coronasizescale, light->ambientscale, light->diffusescale, light->specularscale, light->flags);
+                       dpsnprintf(line, sizeof(line), "%s%f %f %f %f %f %f %f %d \"%s\" %f %f %f %f %f %f %f %f %i\n", light->shadow ? "" : "!", light->origin[0], light->origin[1], light->origin[2], light->radius, light->color[0], light->color[1], light->color[2], light->style, light->cubemapname, light->corona, light->angles[0], light->angles[1], light->angles[2], light->coronasizescale, light->ambientscale, light->diffusescale, light->specularscale, light->flags);
                else if (light->cubemapname[0] || light->corona || light->angles[0] || light->angles[1] || light->angles[2])
-                       sprintf(line, "%s%f %f %f %f %f %f %f %d \"%s\" %f %f %f %f\n", light->shadow ? "" : "!", light->origin[0], light->origin[1], light->origin[2], light->radius, light->color[0], light->color[1], light->color[2], light->style, light->cubemapname, light->corona, light->angles[0], light->angles[1], light->angles[2]);
+                       dpsnprintf(line, sizeof(line), "%s%f %f %f %f %f %f %f %d \"%s\" %f %f %f %f\n", light->shadow ? "" : "!", light->origin[0], light->origin[1], light->origin[2], light->radius, light->color[0], light->color[1], light->color[2], light->style, light->cubemapname, light->corona, light->angles[0], light->angles[1], light->angles[2]);
                else
-                       sprintf(line, "%s%f %f %f %f %f %f %f %d\n", light->shadow ? "" : "!", light->origin[0], light->origin[1], light->origin[2], light->radius, light->color[0], light->color[1], light->color[2], light->style);
+                       dpsnprintf(line, sizeof(line), "%s%f %f %f %f %f %f %f %d\n", light->shadow ? "" : "!", light->origin[0], light->origin[1], light->origin[2], light->radius, light->color[0], light->color[1], light->color[2], light->style);
                if (bufchars + strlen(line) > bufmaxchars)
                {
                        bufmaxchars = bufchars + strlen(line) + 2048;
@@ -3738,12 +3905,12 @@ void R_Shadow_LoadLightsFile(void)
        int n, a, style;
        char tempchar, *lightsstring, *s, *t, name[MAX_QPATH];
        float origin[3], radius, color[3], subtract, spotdir[3], spotcone, falloff, distbias;
-       if (r_refdef.worldmodel == NULL)
+       if (cl.worldmodel == NULL)
        {
                Con_Print("No map loaded.\n");
                return;
        }
-       FS_StripExtension (r_refdef.worldmodel->name, name, sizeof (name));
+       FS_StripExtension (cl.worldmodel->name, name, sizeof (name));
        strlcat (name, ".lights", sizeof (name));
        lightsstring = (char *)FS_LoadFile(name, tempmempool, false, NULL);
        if (lightsstring)
@@ -3793,18 +3960,18 @@ void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void)
        float origin[3], angles[3], radius, color[3], light[4], fadescale, lightscale, originhack[3], overridecolor[3], vec[4];
        char key[256], value[MAX_INPUTLINE];
 
-       if (r_refdef.worldmodel == NULL)
+       if (cl.worldmodel == NULL)
        {
                Con_Print("No map loaded.\n");
                return;
        }
        // try to load a .ent file first
-       FS_StripExtension (r_refdef.worldmodel->name, key, sizeof (key));
+       FS_StripExtension (cl.worldmodel->name, key, sizeof (key));
        strlcat (key, ".ent", sizeof (key));
        data = entfiledata = (char *)FS_LoadFile(key, tempmempool, true, NULL);
        // and if that is not found, fall back to the bsp file entity string
        if (!data)
-               data = r_refdef.worldmodel->brush.entities;
+               data = cl.worldmodel->brush.entities;
        if (!data)
                return;
        for (entnum = 0;COM_ParseToken_Simple(&data, false, false) && com_token[0] == '{';entnum++)
@@ -3950,7 +4117,7 @@ void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void)
                                pflags = (int)atof(value);
                        else if (!strcmp("effects", key))
                                effects = (int)atof(value);
-                       else if (r_refdef.worldmodel->type == mod_brushq3)
+                       else if (cl.worldmodel->type == mod_brushq3)
                        {
                                if (!strcmp("scale", key))
                                        lightscale = atof(value);
@@ -4008,8 +4175,8 @@ void R_Shadow_SetCursorLocationForView(void)
        vec_t dist, push;
        vec3_t dest, endpos;
        trace_t trace;
-       VectorMA(r_view.origin, r_editlights_cursordistance.value, r_view.forward, dest);
-       trace = CL_Move(r_view.origin, vec3_origin, vec3_origin, dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false);
+       VectorMA(r_refdef.view.origin, r_editlights_cursordistance.value, r_refdef.view.forward, dest);
+       trace = CL_Move(r_refdef.view.origin, vec3_origin, vec3_origin, dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false);
        if (trace.fraction < 1)
        {
                dist = trace.fraction * r_editlights_cursordistance.value;
@@ -4017,7 +4184,7 @@ void R_Shadow_SetCursorLocationForView(void)
                if (push > dist)
                        push = dist;
                push = -push;
-               VectorMA(trace.endpos, push, r_view.forward, endpos);
+               VectorMA(trace.endpos, push, r_refdef.view.forward, endpos);
                VectorMA(endpos, r_editlights_cursorpushoff.value, trace.plane.normal, endpos);
        }
        else
@@ -4047,9 +4214,9 @@ void R_Shadow_EditLights_Clear_f(void)
 
 void R_Shadow_EditLights_Reload_f(void)
 {
-       if (!r_refdef.worldmodel)
+       if (!cl.worldmodel)
                return;
-       strlcpy(r_shadow_mapname, r_refdef.worldmodel->name, sizeof(r_shadow_mapname));
+       strlcpy(r_shadow_mapname, cl.worldmodel->name, sizeof(r_shadow_mapname));
        R_Shadow_ClearWorldLights();
        R_Shadow_LoadWorldLights();
        if (!Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray))
@@ -4062,7 +4229,7 @@ void R_Shadow_EditLights_Reload_f(void)
 
 void R_Shadow_EditLights_Save_f(void)
 {
-       if (!r_refdef.worldmodel)
+       if (!cl.worldmodel)
                return;
        R_Shadow_SaveWorldLights();
 }
@@ -4415,6 +4582,7 @@ void R_Shadow_EditLights_EditAll_f(void)
 {
        size_t lightindex;
        dlight_t *light;
+       size_t range;
 
        if (!r_editlights.integer)
        {
@@ -4422,9 +4590,11 @@ void R_Shadow_EditLights_EditAll_f(void)
                return;
        }
 
-       for (lightindex = 0;lightindex < Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray);lightindex++)
+       // EditLights doesn't seem to have a "remove" command or something so:
+       range = Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray); // checked
+       for (lightindex = 0;lightindex < range;lightindex++)
        {
-               light = Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+               light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
                if (!light)
                        continue;
                R_Shadow_SelectLight(light);
@@ -4435,7 +4605,7 @@ void R_Shadow_EditLights_EditAll_f(void)
 void R_Shadow_EditLights_DrawSelectedLightProperties(void)
 {
        int lightnumber, lightcount;
-       size_t lightindex;
+       size_t lightindex, range;
        dlight_t *light;
        float x, y;
        char temp[256];
@@ -4446,35 +4616,36 @@ void R_Shadow_EditLights_DrawSelectedLightProperties(void)
        DrawQ_Pic(x-5, y-5, NULL, 250, 155, 0, 0, 0, 0.75, 0);
        lightnumber = -1;
        lightcount = 0;
-       for (lightindex = 0;lightindex < Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray);lightindex++)
+       range = Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray); // checked
+       for (lightindex = 0;lightindex < range;lightindex++)
        {
-               light = Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+               light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
                if (!light)
                        continue;
                if (light == r_shadow_selectedlight)
                        lightnumber = lightindex;
                lightcount++;
        }
-       sprintf(temp, "Cursor origin: %.0f %.0f %.0f", r_editlights_cursorlocation[0], r_editlights_cursorlocation[1], r_editlights_cursorlocation[2]); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, false);y += 8;
-       sprintf(temp, "Total lights : %i active (%i total)", lightcount, (int)Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray)); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, false);y += 8;
+       dpsnprintf(temp, sizeof(temp), "Cursor origin: %.0f %.0f %.0f", r_editlights_cursorlocation[0], r_editlights_cursorlocation[1], r_editlights_cursorlocation[2]); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, false);y += 8;
+       dpsnprintf(temp, sizeof(temp), "Total lights : %i active (%i total)", lightcount, (int)Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray)); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, false);y += 8;
        y += 8;
        if (r_shadow_selectedlight == NULL)
                return;
-       sprintf(temp, "Light #%i properties:", lightnumber);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
-       sprintf(temp, "Origin       : %.0f %.0f %.0f\n", r_shadow_selectedlight->origin[0], r_shadow_selectedlight->origin[1], r_shadow_selectedlight->origin[2]);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
-       sprintf(temp, "Angles       : %.0f %.0f %.0f\n", r_shadow_selectedlight->angles[0], r_shadow_selectedlight->angles[1], r_shadow_selectedlight->angles[2]);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
-       sprintf(temp, "Color        : %.2f %.2f %.2f\n", r_shadow_selectedlight->color[0], r_shadow_selectedlight->color[1], r_shadow_selectedlight->color[2]);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
-       sprintf(temp, "Radius       : %.0f\n", r_shadow_selectedlight->radius);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
-       sprintf(temp, "Corona       : %.0f\n", r_shadow_selectedlight->corona);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
-       sprintf(temp, "Style        : %i\n", r_shadow_selectedlight->style);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
-       sprintf(temp, "Shadows      : %s\n", r_shadow_selectedlight->shadow ? "yes" : "no");DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
-       sprintf(temp, "Cubemap      : %s\n", r_shadow_selectedlight->cubemapname);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
-       sprintf(temp, "CoronaSize   : %.2f\n", r_shadow_selectedlight->coronasizescale);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
-       sprintf(temp, "Ambient      : %.2f\n", r_shadow_selectedlight->ambientscale);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
-       sprintf(temp, "Diffuse      : %.2f\n", r_shadow_selectedlight->diffusescale);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
-       sprintf(temp, "Specular     : %.2f\n", r_shadow_selectedlight->specularscale);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
-       sprintf(temp, "NormalMode   : %s\n", (r_shadow_selectedlight->flags & LIGHTFLAG_NORMALMODE) ? "yes" : "no");DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
-       sprintf(temp, "RealTimeMode : %s\n", (r_shadow_selectedlight->flags & LIGHTFLAG_REALTIMEMODE) ? "yes" : "no");DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
+       dpsnprintf(temp, sizeof(temp), "Light #%i properties:", lightnumber);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
+       dpsnprintf(temp, sizeof(temp), "Origin       : %.0f %.0f %.0f\n", r_shadow_selectedlight->origin[0], r_shadow_selectedlight->origin[1], r_shadow_selectedlight->origin[2]);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
+       dpsnprintf(temp, sizeof(temp), "Angles       : %.0f %.0f %.0f\n", r_shadow_selectedlight->angles[0], r_shadow_selectedlight->angles[1], r_shadow_selectedlight->angles[2]);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
+       dpsnprintf(temp, sizeof(temp), "Color        : %.2f %.2f %.2f\n", r_shadow_selectedlight->color[0], r_shadow_selectedlight->color[1], r_shadow_selectedlight->color[2]);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
+       dpsnprintf(temp, sizeof(temp), "Radius       : %.0f\n", r_shadow_selectedlight->radius);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
+       dpsnprintf(temp, sizeof(temp), "Corona       : %.0f\n", r_shadow_selectedlight->corona);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
+       dpsnprintf(temp, sizeof(temp), "Style        : %i\n", r_shadow_selectedlight->style);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
+       dpsnprintf(temp, sizeof(temp), "Shadows      : %s\n", r_shadow_selectedlight->shadow ? "yes" : "no");DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
+       dpsnprintf(temp, sizeof(temp), "Cubemap      : %s\n", r_shadow_selectedlight->cubemapname);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
+       dpsnprintf(temp, sizeof(temp), "CoronaSize   : %.2f\n", r_shadow_selectedlight->coronasizescale);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
+       dpsnprintf(temp, sizeof(temp), "Ambient      : %.2f\n", r_shadow_selectedlight->ambientscale);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
+       dpsnprintf(temp, sizeof(temp), "Diffuse      : %.2f\n", r_shadow_selectedlight->diffusescale);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
+       dpsnprintf(temp, sizeof(temp), "Specular     : %.2f\n", r_shadow_selectedlight->specularscale);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
+       dpsnprintf(temp, sizeof(temp), "NormalMode   : %s\n", (r_shadow_selectedlight->flags & LIGHTFLAG_NORMALMODE) ? "yes" : "no");DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
+       dpsnprintf(temp, sizeof(temp), "RealTimeMode : %s\n", (r_shadow_selectedlight->flags & LIGHTFLAG_REALTIMEMODE) ? "yes" : "no");DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8;
 }
 
 void R_Shadow_EditLights_ToggleShadow_f(void)
@@ -4661,10 +4832,10 @@ void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffu
        VectorClear(diffusecolor);
        VectorClear(diffusenormal);
 
-       if (!r_fullbright.integer && r_refdef.worldmodel && r_refdef.worldmodel->brush.LightPoint)
+       if (!r_fullbright.integer && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.LightPoint)
        {
-               ambientcolor[0] = ambientcolor[1] = ambientcolor[2] = r_ambient.value * (2.0f / 128.0f);
-               r_refdef.worldmodel->brush.LightPoint(r_refdef.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
+               ambientcolor[0] = ambientcolor[1] = ambientcolor[2] = r_refdef.scene.ambient * (2.0f / 128.0f);
+               r_refdef.scene.worldmodel->brush.LightPoint(r_refdef.scene.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
        }
        else
                VectorSet(ambientcolor, 1, 1, 1);
@@ -4674,9 +4845,9 @@ void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffu
                int i;
                float f, v[3];
                rtlight_t *light;
-               for (i = 0;i < r_refdef.numlights;i++)
+               for (i = 0;i < r_refdef.scene.numlights;i++)
                {
-                       light = &r_refdef.lights[i];
+                       light = &r_refdef.scene.lights[i];
                        Matrix4x4_Transform(&light->matrix_worldtolight, p, v);
                        f = 1 - VectorLength2(v);
                        if (f > 0 && CL_Move(p, vec3_origin, vec3_origin, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction == 1)