]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - r_shadow.c
with utf8 disabled, str2chr should now behave the way it used to
[xonotic/darkplaces.git] / r_shadow.c
index 736b02859eeef542335b1d777f3abdb49eb6b9b2..56c387f986c6d9b1d86581d9ea136244f2a8f2ee 100644 (file)
@@ -140,8 +140,6 @@ demonstrated by the game Doom3.
 #include "portals.h"
 #include "image.h"
 
-#define R_SHADOW_SHADOWMAP_NUMCUBEMAPS 8
-
 extern void R_Shadow_EditLights_Init(void);
 
 typedef enum r_shadow_rendermode_e
@@ -288,8 +286,7 @@ cvar_t r_shadow_lightattenuationdividebias = {0, "r_shadow_lightattenuationdivid
 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"};
 cvar_t r_shadow_lightradiusscale = {0, "r_shadow_lightradiusscale", "1", "renders all world lights larger or smaller"};
-cvar_t r_shadow_portallight = {0, "r_shadow_portallight", "1", "use portal culling to exactly determine lit triangles when compiling world lights"};
-cvar_t r_shadow_projectdistance = {0, "r_shadow_projectdistance", "1000000", "how far to cast shadows"};
+cvar_t r_shadow_projectdistance = {0, "r_shadow_projectdistance", "0", "how far to cast shadows"};
 cvar_t r_shadow_frontsidecasting = {0, "r_shadow_frontsidecasting", "1", "whether to cast shadows from illuminated triangles (front side of model) or unlit triangles (back side of model)"};
 cvar_t r_shadow_realtime_dlight = {CVAR_SAVE, "r_shadow_realtime_dlight", "1", "enables rendering of dynamic lights such as explosions and rocket light"};
 cvar_t r_shadow_realtime_dlight_shadows = {CVAR_SAVE, "r_shadow_realtime_dlight_shadows", "1", "enables rendering of shadows from dynamic lights"};
@@ -300,8 +297,8 @@ cvar_t r_shadow_realtime_world_lightmaps = {CVAR_SAVE, "r_shadow_realtime_world_
 cvar_t r_shadow_realtime_world_shadows = {CVAR_SAVE, "r_shadow_realtime_world_shadows", "1", "enables rendering of shadows from world lights"};
 cvar_t r_shadow_realtime_world_compile = {0, "r_shadow_realtime_world_compile", "1", "enables compilation of world lights for higher performance rendering"};
 cvar_t r_shadow_realtime_world_compileshadow = {0, "r_shadow_realtime_world_compileshadow", "1", "enables compilation of shadows from world lights for higher performance rendering"};
-cvar_t r_shadow_realtime_world_compilesvbsp = {0, "r_shadow_realtime_world_compilesvbsp", "1", "enables svbsp optimization during compilation"};
-cvar_t r_shadow_realtime_world_compileportalculling = {0, "r_shadow_realtime_world_compileportalculling", "1", "enables portal-based culling optimization during compilation"};
+cvar_t r_shadow_realtime_world_compilesvbsp = {0, "r_shadow_realtime_world_compilesvbsp", "1", "enables svbsp optimization during compilation (slower than compileportalculling but more exact)"};
+cvar_t r_shadow_realtime_world_compileportalculling = {0, "r_shadow_realtime_world_compileportalculling", "0", "enables portal-based culling optimization during compilation (overrides compilesvbsp)"};
 cvar_t r_shadow_scissor = {0, "r_shadow_scissor", "1", "use scissor optimization of light rendering (restricts rendering to the portion of the screen affected by the light)"};
 cvar_t r_shadow_shadowmapping = {CVAR_SAVE, "r_shadow_shadowmapping", "0", "enables use of shadowmapping (depth texture sampling) instead of stencil shadow volumes, requires gl_fbo 1"};
 cvar_t r_shadow_shadowmapping_texturetype = {CVAR_SAVE, "r_shadow_shadowmapping_texturetype", "-1", "shadowmap texture types: -1 = auto-select, 0 = 2D, 1 = rectangle, 2 = cubemap"};
@@ -318,7 +315,6 @@ cvar_t r_shadow_shadowmapping_nearclip = {CVAR_SAVE, "r_shadow_shadowmapping_nea
 cvar_t r_shadow_shadowmapping_bias = {CVAR_SAVE, "r_shadow_shadowmapping_bias", "0.03", "shadowmap bias parameter (this is multiplied by nearclip * 1024 / lodsize)"};
 cvar_t r_shadow_shadowmapping_polygonfactor = {CVAR_SAVE, "r_shadow_shadowmapping_polygonfactor", "2", "slope-dependent shadowmapping bias"};
 cvar_t r_shadow_shadowmapping_polygonoffset = {CVAR_SAVE, "r_shadow_shadowmapping_polygonoffset", "0", "constant shadowmapping bias"};
-cvar_t r_shadow_culltriangles = {0, "r_shadow_culltriangles", "1", "performs more expensive tests to remove unnecessary triangles of lit surfaces"};
 cvar_t r_shadow_polygonfactor = {0, "r_shadow_polygonfactor", "0", "how much to enlarge shadow volume polygons when rendering (should be 0!)"};
 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 OpenGL 2.0 render path)"};
@@ -398,6 +394,7 @@ void R_Shadow_SetShadowMode(void)
        switch(vid.renderpath)
        {
        case RENDERPATH_GL20:
+       case RENDERPATH_CGGL:
                if ((r_shadow_shadowmapping.integer || r_shadow_deferred.integer) && vid.support.ext_framebuffer_object)
                {
                        if(r_shadow_shadowmapfilterquality < 0)
@@ -682,7 +679,6 @@ void R_Shadow_Init(void)
        Cvar_RegisterVariable(&r_shadow_lightattenuationlinearscale);
        Cvar_RegisterVariable(&r_shadow_lightintensityscale);
        Cvar_RegisterVariable(&r_shadow_lightradiusscale);
-       Cvar_RegisterVariable(&r_shadow_portallight);
        Cvar_RegisterVariable(&r_shadow_projectdistance);
        Cvar_RegisterVariable(&r_shadow_frontsidecasting);
        Cvar_RegisterVariable(&r_shadow_realtime_dlight);
@@ -712,7 +708,6 @@ void R_Shadow_Init(void)
        Cvar_RegisterVariable(&r_shadow_shadowmapping_bias);
        Cvar_RegisterVariable(&r_shadow_shadowmapping_polygonfactor);
        Cvar_RegisterVariable(&r_shadow_shadowmapping_polygonoffset);
-       Cvar_RegisterVariable(&r_shadow_culltriangles);
        Cvar_RegisterVariable(&r_shadow_polygonfactor);
        Cvar_RegisterVariable(&r_shadow_polygonoffset);
        Cvar_RegisterVariable(&r_shadow_texture3d);
@@ -1335,7 +1330,6 @@ void R_Shadow_VolumeFromList(int numverts, int numtris, const float *invertex3f,
                r_refdef.stats.lights_shadowtriangles += tris;
                CHECKGLERROR
                R_Mesh_VertexPointer(shadowvertex3f, 0, 0);
-               GL_LockArrays(0, outverts);
                if (r_shadow_rendermode == R_SHADOW_RENDERMODE_ZPASS_STENCIL)
                {
                        // increment stencil if frontface is infront of depthbuffer
@@ -1357,7 +1351,6 @@ void R_Shadow_VolumeFromList(int numverts, int numtris, const float *invertex3f,
                        qglStencilOp(GL_KEEP, GL_INCR, GL_KEEP);CHECKGLERROR
                }
                R_Mesh_Draw(0, outverts, 0, tris, shadowelements, NULL, 0, 0);
-               GL_LockArrays(0, 0);
                CHECKGLERROR
        }
 }
@@ -1910,6 +1903,7 @@ void R_Shadow_RenderMode_Begin(void)
        switch(vid.renderpath)
        {
        case RENDERPATH_GL20:
+       case RENDERPATH_CGGL:
                r_shadow_lightingrendermode = R_SHADOW_RENDERMODE_LIGHT_GLSL;
                break;
        case RENDERPATH_GL13:
@@ -1975,7 +1969,7 @@ void R_Shadow_RenderMode_Reset(void)
        GL_Color(1, 1, 1, 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);
+       R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
        r_shadow_usingshadowmaprect = false;
        r_shadow_usingshadowmapcube = false;
        r_shadow_usingshadowmap2d = false;
@@ -1998,7 +1992,7 @@ void R_Shadow_RenderMode_StencilShadowVolumes(qboolean zpass)
        R_Shadow_RenderMode_Reset();
        GL_ColorMask(0, 0, 0, 0);
        GL_PolygonOffset(r_refdef.shadowpolygonfactor, r_refdef.shadowpolygonoffset);CHECKGLERROR
-       R_SetupDepthOrShadowShader();
+       R_SetupShader_DepthOrShadow();
        qglDepthFunc(GL_LESS);CHECKGLERROR
        qglEnable(GL_STENCIL_TEST);CHECKGLERROR
        r_shadow_rendermode = mode;
@@ -2184,11 +2178,11 @@ void R_Shadow_RenderMode_ShadowMap(int side, qboolean clear, int size)
        if (fbo)
        {
                qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);CHECKGLERROR
-               R_SetupDepthOrShadowShader();
+               R_SetupShader_DepthOrShadow();
        }
        else
        {
-               R_SetupShowDepthShader();
+               R_SetupShader_ShowDepth();
                qglClearColor(1,1,1,1);CHECKGLERROR
        }
        CHECKGLERROR
@@ -2217,34 +2211,6 @@ init_done:
        CHECKGLERROR
 }
 
-void R_Shadow_RenderMode_SetShadowMapTexture(void)
-{
-       if (r_shadow_shadowmode == R_SHADOW_SHADOWMODE_SHADOWMAP2D)
-       {
-               r_shadow_usingshadowmap2d = true;
-               R_Mesh_TexBind(GL20TU_SHADOWMAP2D, R_GetTexture(r_shadow_shadowmap2dtexture));
-               CHECKGLERROR
-       }
-       else if (r_shadow_shadowmode == R_SHADOW_SHADOWMODE_SHADOWMAPRECTANGLE)
-       {
-               r_shadow_usingshadowmaprect = true;
-               R_Mesh_TexBindAll(GL20TU_SHADOWMAPRECT, 0, 0, 0, R_GetTexture(r_shadow_shadowmaprectangletexture));
-               CHECKGLERROR
-       }
-       else if (r_shadow_shadowmode == R_SHADOW_SHADOWMODE_SHADOWMAPCUBESIDE)
-       {
-               r_shadow_usingshadowmapcube = true;
-               R_Mesh_TexBindAll(GL20TU_SHADOWMAPCUBE, 0, 0, R_GetTexture(r_shadow_shadowmapcubetexture[r_shadow_shadowmaplod]), 0);
-               CHECKGLERROR
-       }
-
-       if (r_shadow_shadowmapvsdct && (r_shadow_usingshadowmap2d || r_shadow_usingshadowmaprect))
-       {
-               R_Mesh_TexBindAll(GL20TU_CUBEPROJECTION, 0, 0, R_GetTexture(r_shadow_shadowmapvsdcttexture), 0);
-               CHECKGLERROR
-       }
-}
-
 void R_Shadow_RenderMode_Lighting(qboolean stenciltest, qboolean transparent, qboolean shadowmapping)
 {
        if (transparent)
@@ -2272,11 +2238,17 @@ void R_Shadow_RenderMode_Lighting(qboolean stenciltest, qboolean transparent, qb
        // do global setup needed for the chosen lighting mode
        if (r_shadow_rendermode == R_SHADOW_RENDERMODE_LIGHT_GLSL)
        {
-               R_Mesh_TexBindAll(GL20TU_CUBE, 0, 0, R_GetTexture(rsurface.rtlight->currentcubemap), 0); // light filter
                GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 0);
                CHECKGLERROR
-               if (shadowmapping)
-                       R_Shadow_RenderMode_SetShadowMapTexture();
+       }
+       if (shadowmapping)
+       {
+               if (r_shadow_shadowmode == R_SHADOW_SHADOWMODE_SHADOWMAP2D)
+                       r_shadow_usingshadowmap2d = true;
+               else if (r_shadow_shadowmode == R_SHADOW_SHADOWMODE_SHADOWMAPRECTANGLE)
+                       r_shadow_usingshadowmaprect = true;
+               else if (r_shadow_shadowmode == R_SHADOW_SHADOWMODE_SHADOWMAPCUBESIDE)
+                       r_shadow_usingshadowmapcube = true;
        }
        R_Mesh_ColorPointer(rsurface.array_color4f, 0, 0);
        CHECKGLERROR
@@ -2313,9 +2285,8 @@ void R_Shadow_RenderMode_DrawDeferredLight(qboolean stenciltest, qboolean shadow
        R_Shadow_RenderMode_Reset();
        r_shadow_rendermode = r_shadow_lightingrendermode;
        // do global setup needed for the chosen lighting mode
-       if (r_shadow_rendermode == R_SHADOW_RENDERMODE_LIGHT_GLSL)
        {
-               R_Mesh_Matrix(&identitymatrix);
+               R_EntityMatrix(&identitymatrix);
                GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
                if (stenciltest)
                {
@@ -2325,32 +2296,30 @@ void R_Shadow_RenderMode_DrawDeferredLight(qboolean stenciltest, qboolean shadow
                        qglStencilFunc(GL_EQUAL, 128, ~0);CHECKGLERROR
                }
                qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, r_shadow_prepasslightingfbo);CHECKGLERROR
-               R_Mesh_TexBindAll(GL20TU_SCREENDEPTH, 0, 0, 0, R_GetTexture(r_shadow_prepassgeometrydepthtexture));
-               R_Mesh_TexBindAll(GL20TU_SCREENNORMALMAP, 0, 0, 0, R_GetTexture(r_shadow_prepassgeometrynormalmaptexture));
-               R_Mesh_TexBindAll(GL20TU_CUBE, 0, 0, R_GetTexture(rsurface.rtlight->currentcubemap), 0); // light filter
                if (shadowmapping)
-                       R_Shadow_RenderMode_SetShadowMapTexture();
-               R_SetupDeferredLightShader(rsurface.rtlight);
-               //R_Mesh_TexBind(GL20TU_FOGMASK, R_GetTexture(r_texture_fogattenuation));
-               R_Mesh_TexBind(GL20TU_ATTENUATION, R_GetTexture(r_shadow_attenuationgradienttexture));
+               {
+                       if (r_shadow_shadowmode == R_SHADOW_SHADOWMODE_SHADOWMAP2D)
+                               r_shadow_usingshadowmap2d = true;
+                       else if (r_shadow_shadowmode == R_SHADOW_SHADOWMODE_SHADOWMAPRECTANGLE)
+                               r_shadow_usingshadowmaprect = true;
+                       else if (r_shadow_shadowmode == R_SHADOW_SHADOWMODE_SHADOWMAPCUBESIDE)
+                               r_shadow_usingshadowmapcube = true;
+               }
 
+               // render the lighting
+               R_SetupShader_DeferredLight(rsurface.rtlight);
                for (i = 0;i < 8;i++)
                        Matrix4x4_Transform(matrix, bboxpoints[i], vertex3f + i*3);
                CHECKGLERROR
-               //qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);CHECKGLERROR
                R_Mesh_VertexPointer(vertex3f, 0, 0);
                R_Mesh_ColorPointer(NULL, 0, 0);
                GL_ColorMask(1,1,1,1);
-               //GL_Color(0.25f,0.05f,0.02f,1.0f);
-               //R_SetupGenericShader(false);
                GL_DepthMask(false);
                GL_DepthRange(0, 1);
                GL_PolygonOffset(0, 0);
                GL_DepthTest(true);
                qglDepthFunc(GL_GREATER);CHECKGLERROR
                GL_CullFace(r_refdef.view.cullface_back);
-               //GL_AlphaTest(false);
-               //qglDisable(GL_STENCIL_TEST);CHECKGLERROR
                R_Mesh_Draw(0, 8, 0, 12, NULL, bboxelements, 0, 0);
        }
 }
@@ -2710,33 +2679,7 @@ static void R_Shadow_RenderLighting_VisibleLighting(int firstvertex, int numvert
 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 lightcolor, float ambientscale, float diffusescale, float specularscale)
 {
        // ARB2 GLSL shader path (GFFX5200, Radeon 9500)
-       R_SetupSurfaceShader(lightcolor, 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_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_TexBind(GL20TU_SECONDARY_GLOW, R_GetTexture(rsurface.texture->backgroundcurrentskinframe->glow));
-       }
-       //R_Mesh_TexBindAll(GL20TU_CUBE, 0, 0, R_GetTexture(rsurface.rtlight->currentcubemap), 0);
-       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);
-       R_Mesh_TexCoordPointer(3, 3, rsurface.normal3f, rsurface.normal3f_bufferobject, rsurface.normal3f_bufferoffset);
+       R_SetupShader_Surface(lightcolor, false, ambientscale, diffusescale, specularscale, RSURFPASS_RTLIGHT);
        if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
        {
                qglDepthFunc(GL_EQUAL);CHECKGLERROR
@@ -2847,8 +2790,8 @@ static void R_Shadow_RenderLighting_Light_Vertex(int firstvertex, int numvertice
        const float *surfacepants = rsurface.colormap_pantscolor;
        const float *surfaceshirt = rsurface.colormap_shirtcolor;
        rtexture_t *basetexture = rsurface.texture->basetexture;
-       rtexture_t *pantstexture = rsurface.texture->currentskinframe->pants;
-       rtexture_t *shirttexture = rsurface.texture->currentskinframe->shirt;
+       rtexture_t *pantstexture = rsurface.texture->pantstexture;
+       rtexture_t *shirttexture = rsurface.texture->shirttexture;
        qboolean dopants = pantstexture && VectorLength2(surfacepants) >= (1.0f / 1048576.0f);
        qboolean doshirt = shirttexture && VectorLength2(surfaceshirt) >= (1.0f / 1048576.0f);
        ambientscale *= 2 * r_refdef.view.colorscale;
@@ -2859,26 +2802,26 @@ static void R_Shadow_RenderLighting_Light_Vertex(int firstvertex, int numvertice
        diffusecolorpants[0] = diffusecolorbase[0] * surfacepants[0];diffusecolorpants[1] = diffusecolorbase[1] * surfacepants[1];diffusecolorpants[2] = diffusecolorbase[2] * surfacepants[2];
        ambientcolorshirt[0] = ambientcolorbase[0] * surfaceshirt[0];ambientcolorshirt[1] = ambientcolorbase[1] * surfaceshirt[1];ambientcolorshirt[2] = ambientcolorbase[2] * surfaceshirt[2];
        diffusecolorshirt[0] = diffusecolorbase[0] * surfaceshirt[0];diffusecolorshirt[1] = diffusecolorbase[1] * surfaceshirt[1];diffusecolorshirt[2] = diffusecolorbase[2] * surfaceshirt[2];
-       R_Mesh_TexBind(0, R_GetTexture(basetexture));
+       R_Mesh_TexBind(0, basetexture);
        R_Mesh_TexMatrix(0, &rsurface.texture->currenttexmatrix);
        R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
        R_Mesh_TexCoordPointer(0, 2, rsurface.texcoordtexture2f, rsurface.texcoordtexture2f_bufferobject, rsurface.texcoordtexture2f_bufferoffset);
        switch(r_shadow_rendermode)
        {
        case R_SHADOW_RENDERMODE_LIGHT_VERTEX3DATTEN:
-               R_Mesh_TexBindAll(1, 0, R_GetTexture(r_shadow_attenuation3dtexture), 0, 0);
+               R_Mesh_TexBind(1, r_shadow_attenuation3dtexture);
                R_Mesh_TexMatrix(1, &rsurface.entitytoattenuationxyz);
                R_Mesh_TexCombine(1, GL_MODULATE, GL_MODULATE, 1, 1);
                R_Mesh_TexCoordPointer(1, 3, rsurface.vertex3f, rsurface.vertex3f_bufferobject, rsurface.vertex3f_bufferoffset);
                break;
        case R_SHADOW_RENDERMODE_LIGHT_VERTEX2D1DATTEN:
-               R_Mesh_TexBind(2, R_GetTexture(r_shadow_attenuation2dtexture));
+               R_Mesh_TexBind(2, r_shadow_attenuation2dtexture);
                R_Mesh_TexMatrix(2, &rsurface.entitytoattenuationz);
                R_Mesh_TexCombine(2, GL_MODULATE, GL_MODULATE, 1, 1);
                R_Mesh_TexCoordPointer(2, 3, rsurface.vertex3f, rsurface.vertex3f_bufferobject, rsurface.vertex3f_bufferoffset);
                // fall through
        case R_SHADOW_RENDERMODE_LIGHT_VERTEX2DATTEN:
-               R_Mesh_TexBind(1, R_GetTexture(r_shadow_attenuation2dtexture));
+               R_Mesh_TexBind(1, r_shadow_attenuation2dtexture);
                R_Mesh_TexMatrix(1, &rsurface.entitytoattenuationxyz);
                R_Mesh_TexCombine(1, GL_MODULATE, GL_MODULATE, 1, 1);
                R_Mesh_TexCoordPointer(1, 3, rsurface.vertex3f, rsurface.vertex3f_bufferobject, rsurface.vertex3f_bufferoffset);
@@ -2888,16 +2831,16 @@ static void R_Shadow_RenderLighting_Light_Vertex(int firstvertex, int numvertice
        default:
                break;
        }
-       //R_Mesh_TexBind(0, R_GetTexture(basetexture));
+       //R_Mesh_TexBind(0, basetexture);
        R_Shadow_RenderLighting_Light_Vertex_Pass(firstvertex, numvertices, numtriangles, element3i, diffusecolorbase, ambientcolorbase);
        if (dopants)
        {
-               R_Mesh_TexBind(0, R_GetTexture(pantstexture));
+               R_Mesh_TexBind(0, pantstexture);
                R_Shadow_RenderLighting_Light_Vertex_Pass(firstvertex, numvertices, numtriangles, element3i, diffusecolorpants, ambientcolorpants);
        }
        if (doshirt)
        {
-               R_Mesh_TexBind(0, R_GetTexture(shirttexture));
+               R_Mesh_TexBind(0, shirttexture);
                R_Shadow_RenderLighting_Light_Vertex_Pass(firstvertex, numvertices, numtriangles, element3i, diffusecolorshirt, ambientcolorshirt);
        }
 }
@@ -3094,8 +3037,8 @@ void R_RTLight_Compile(rtlight_t *rtlight)
                        if (CHECKPVSBIT(rtlight->static_shadowtrispvs, i))
                                shadowtris++;
 
-       if (developer.integer >= 10)
-               Con_Printf("static light built: %f %f %f : %f %f %f box, %i light triangles, %i shadow triangles, %i zpass/%i zfail compiled shadow volume triangles\n", rtlight->cullmins[0], rtlight->cullmins[1], rtlight->cullmins[2], rtlight->cullmaxs[0], rtlight->cullmaxs[1], rtlight->cullmaxs[2], lighttris, shadowtris, shadowzpasstris, shadowzfailtris);
+       if (developer_extra.integer)
+               Con_DPrintf("static light built: %f %f %f : %f %f %f box, %i light triangles, %i shadow triangles, %i zpass/%i zfail compiled shadow volume triangles\n", rtlight->cullmins[0], rtlight->cullmins[1], rtlight->cullmins[2], rtlight->cullmaxs[0], rtlight->cullmaxs[1], rtlight->cullmaxs[2], lighttris, shadowtris, shadowzpasstris, shadowzfailtris);
 }
 
 void R_RTLight_Uncompile(rtlight_t *rtlight)
@@ -3358,7 +3301,6 @@ void R_Shadow_DrawWorldShadow_ShadowVolume(int numsurfaces, int *surfacelist, co
                {
                        r_refdef.stats.lights_shadowtriangles += mesh->numtriangles;
                        R_Mesh_VertexPointer(mesh->vertex3f, mesh->vbo, mesh->vbooffset_vertex3f);
-                       GL_LockArrays(0, mesh->numverts);
                        if (r_shadow_rendermode == R_SHADOW_RENDERMODE_ZPASS_STENCIL)
                        {
                                // increment stencil if frontface is infront of depthbuffer
@@ -3380,12 +3322,12 @@ void R_Shadow_DrawWorldShadow_ShadowVolume(int numsurfaces, int *surfacelist, co
                                qglStencilOp(GL_KEEP, GL_INCR, GL_KEEP);CHECKGLERROR
                        }
                        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.scene.worldmodel->brush.shadowmesh && r_shadow_culltriangles.integer)
+       else if (numsurfaces && r_refdef.scene.worldmodel->brush.shadowmesh)
        {
+               // use the shadow trispvs calculated earlier by GetLightInfo to cull world triangles on this dynamic light
                R_Shadow_PrepareShadowMark(r_refdef.scene.worldmodel->brush.shadowmesh->numtriangles);
                for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++)
                {
@@ -3408,6 +3350,7 @@ void R_Shadow_DrawEntityShadow(entity_render_t *ent)
        vec_t relativeshadowradius;
        RSurf_ActiveModelEntity(ent, false, false, false);
        Matrix4x4_Transform(&ent->inversematrix, rsurface.rtlight->shadoworigin, relativeshadoworigin);
+       // we need to re-init the shader for each entity because the matrix changed
        relativeshadowradius = rsurface.rtlight->radius / ent->scale;
        relativeshadowmins[0] = relativeshadoworigin[0] - relativeshadowradius;
        relativeshadowmins[1] = relativeshadoworigin[1] - relativeshadowradius;
@@ -3435,7 +3378,7 @@ void R_Shadow_SetupEntityLight(const entity_render_t *ent)
        Matrix4x4_Transform(&ent->inversematrix, rsurface.rtlight->shadoworigin, rsurface.entitylightorigin);
 }
 
-void R_Shadow_DrawWorldLight(int numsurfaces, int *surfacelist, const unsigned char *trispvs)
+void R_Shadow_DrawWorldLight(int numsurfaces, int *surfacelist, const unsigned char *lighttrispvs)
 {
        if (!r_refdef.scene.worldmodel->DrawLight)
                return;
@@ -3448,7 +3391,7 @@ void R_Shadow_DrawWorldLight(int numsurfaces, int *surfacelist, const unsigned c
        Matrix4x4_Concat(&rsurface.entitytoattenuationz, &matrix_attenuationz, &rsurface.entitytolight);
        VectorCopy(rsurface.rtlight->shadoworigin, rsurface.entitylightorigin);
 
-       r_refdef.scene.worldmodel->DrawLight(r_refdef.scene.worldentity, numsurfaces, surfacelist, trispvs);
+       r_refdef.scene.worldmodel->DrawLight(r_refdef.scene.worldentity, numsurfaces, surfacelist, lighttrispvs);
 
        rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
 }
@@ -3990,7 +3933,7 @@ void R_Shadow_DrawPrepass(void)
        if (cl.csqc_vidvars.drawworld && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->DrawPrepass)
                r_refdef.scene.worldmodel->DrawPrepass(r_refdef.scene.worldentity);
        if (r_timereport_active)
-               R_TimeReport("prepassgeometry");
+               R_TimeReport("prepassworld");
 
        for (i = 0;i < r_refdef.scene.numentities;i++)
        {
@@ -4001,6 +3944,9 @@ void R_Shadow_DrawPrepass(void)
                        ent->model->DrawPrepass(ent);
        }
 
+       if (r_timereport_active)
+               R_TimeReport("prepassmodels");
+
        GL_DepthMask(false);
        GL_ColorMask(1,1,1,1);
        GL_Color(1,1,1,1);
@@ -4068,6 +4014,7 @@ void R_Shadow_PrepareLights(void)
        switch (vid.renderpath)
        {
        case RENDERPATH_GL20:
+       case RENDERPATH_CGGL:
                if (!r_shadow_deferred.integer || r_shadow_shadowmode == R_SHADOW_SHADOWMODE_STENCIL || !vid.support.ext_framebuffer_object || !vid.support.arb_texture_rectangle || vid.maxdrawbuffers < 2)
                {
                        r_shadow_usingdeferredprepass = false;
@@ -4304,12 +4251,12 @@ void R_DrawModelShadows(void)
        //GL_Scissor(r_refdef.view.x, vid.height - r_refdef.view.height - 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_EntityMatrix(&identitymatrix);
        //R_Mesh_ResetTextureState();
        R_ResetViewRendering2D();
        R_Mesh_VertexPointer(r_screenvertex3f, 0, 0);
        R_Mesh_ColorPointer(NULL, 0, 0);
-       R_SetupGenericShader(false);
+       R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
 
        // set up a darkening blend on shadowed areas
        GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -4428,7 +4375,7 @@ void R_Shadow_DrawCoronas(void)
        if (r_waterstate.renderingscene)
                return;
        flag = r_refdef.scene.rtworld ? LIGHTFLAG_REALTIMEMODE : LIGHTFLAG_NORMALMODE;
-       R_Mesh_Matrix(&identitymatrix);
+       R_EntityMatrix(&identitymatrix);
 
        range = Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray); // checked
 
@@ -4459,7 +4406,7 @@ void R_Shadow_DrawCoronas(void)
                GL_DepthTest(true);
                R_Mesh_ColorPointer(NULL, 0, 0);
                R_Mesh_ResetTextureState();
-               R_SetupGenericShader(false);
+               R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
        }
        for (lightindex = 0;lightindex < range;lightindex++)
        {
@@ -5732,26 +5679,26 @@ void R_Shadow_EditLights_DrawSelectedLightProperties(void)
                        lightnumber = lightindex;
                lightcount++;
        }
-       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;
+       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, FONT_DEFAULT);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, FONT_DEFAULT);y += 8;
        y += 8;
        if (r_shadow_selectedlight == NULL)
                return;
-       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;
+       dpsnprintf(temp, sizeof(temp), "Light #%i properties:", lightnumber);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT);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, FONT_DEFAULT);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, FONT_DEFAULT);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, FONT_DEFAULT);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, FONT_DEFAULT);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, FONT_DEFAULT);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, FONT_DEFAULT);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, FONT_DEFAULT);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, FONT_DEFAULT);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, FONT_DEFAULT);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, FONT_DEFAULT);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, FONT_DEFAULT);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, FONT_DEFAULT);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, FONT_DEFAULT);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, FONT_DEFAULT);y += 8;
 }
 
 void R_Shadow_EditLights_ToggleShadow_f(void)