]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - r_shadow.c
fix D3D scissoring
[xonotic/darkplaces.git] / r_shadow.c
index f546b146ca6bbd551b1d31ee9eac96a127cf7abc..eb571dd25ddbc5f82ffaa2d627e7ee9179eda6df 100644 (file)
@@ -761,7 +761,7 @@ void R_Shadow_Init(void)
        r_shadow_buffer_surfacesides = NULL;
        r_shadow_buffer_shadowtrispvs = NULL;
        r_shadow_buffer_lighttrispvs = NULL;
-       R_RegisterModule("R_Shadow", r_shadow_start, r_shadow_shutdown, r_shadow_newmap);
+       R_RegisterModule("R_Shadow", r_shadow_start, r_shadow_shutdown, r_shadow_newmap, NULL, NULL);
 }
 
 matrix4x4_t matrix_attenuationxyz =
@@ -1324,8 +1324,8 @@ void R_Shadow_VolumeFromList(int numverts, int numtris, const float *invertex3f,
        else if (r_shadow_rendermode == R_SHADOW_RENDERMODE_VISIBLEVOLUMES)
        {
                tris = R_Shadow_ConstructShadowVolume_ZFail(numverts, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, shadowvertex3f, projectorigin, projectdirection, projectdistance, nummarktris, marktris);
-               R_Mesh_PrepareVertices_Position_Arrays(outverts, shadowvertex3f);
-               R_Mesh_Draw(0, outverts, 0, tris, shadowelements, NULL, 0, NULL, NULL, 0);
+               R_Mesh_VertexPointer(shadowvertex3f, 0, 0);
+               R_Mesh_Draw(0, outverts, 0, tris, shadowelements, NULL, 0, 0);
        }
        else
        {
@@ -1339,12 +1339,13 @@ void R_Shadow_VolumeFromList(int numverts, int numtris, const float *invertex3f,
                r_refdef.stats.lights_dynamicshadowtriangles += tris;
                r_refdef.stats.lights_shadowtriangles += tris;
                CHECKGLERROR
+               R_Mesh_VertexPointer(shadowvertex3f, 0, 0);
                if (r_shadow_rendermode == R_SHADOW_RENDERMODE_ZPASS_STENCIL)
                {
                        // increment stencil if frontface is infront of depthbuffer
                        GL_CullFace(r_refdef.view.cullface_front);
                        qglStencilOp(GL_KEEP, GL_KEEP, GL_DECR);CHECKGLERROR
-                       R_Mesh_Draw(0, outverts, 0, tris, shadowelements, NULL, 0, NULL, NULL, 0);
+                       R_Mesh_Draw(0, outverts, 0, tris, shadowelements, NULL, 0, 0);
                        // decrement stencil if backface is infront of depthbuffer
                        GL_CullFace(r_refdef.view.cullface_back);
                        qglStencilOp(GL_KEEP, GL_KEEP, GL_INCR);CHECKGLERROR
@@ -1354,13 +1355,12 @@ void R_Shadow_VolumeFromList(int numverts, int numtris, const float *invertex3f,
                        // 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, NULL, NULL, 0);
+                       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_PrepareVertices_Position_Arrays(outverts, shadowvertex3f);
-               R_Mesh_Draw(0, outverts, 0, tris, shadowelements, NULL, 0, NULL, NULL, 0);
+               R_Mesh_Draw(0, outverts, 0, tris, shadowelements, NULL, 0, 0);
                CHECKGLERROR
        }
 }
@@ -1754,12 +1754,12 @@ static void R_Shadow_MakeTextures(void)
        // 1D gradient texture
        for (x = 0;x < ATTEN1DSIZE;x++)
                data[x] = R_Shadow_MakeTextures_SamplePoint((x + 0.5f) * (1.0f / ATTEN1DSIZE) * (1.0f / 0.9375), 0, 0);
-       r_shadow_attenuationgradienttexture = R_LoadTexture2D(r_shadow_texturepool, "attenuation1d", ATTEN1DSIZE, 1, (unsigned char *)data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCELINEAR, NULL);
+       r_shadow_attenuationgradienttexture = R_LoadTexture2D(r_shadow_texturepool, "attenuation1d", ATTEN1DSIZE, 1, (unsigned char *)data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCELINEAR, -1, NULL);
        // 2D circle texture
        for (y = 0;y < ATTEN2DSIZE;y++)
                for (x = 0;x < ATTEN2DSIZE;x++)
                        data[y*ATTEN2DSIZE+x] = R_Shadow_MakeTextures_SamplePoint(((x + 0.5f) * (2.0f / ATTEN2DSIZE) - 1.0f) * (1.0f / 0.9375), ((y + 0.5f) * (2.0f / ATTEN2DSIZE) - 1.0f) * (1.0f / 0.9375), 0);
-       r_shadow_attenuation2dtexture = R_LoadTexture2D(r_shadow_texturepool, "attenuation2d", ATTEN2DSIZE, ATTEN2DSIZE, (unsigned char *)data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCELINEAR, NULL);
+       r_shadow_attenuation2dtexture = R_LoadTexture2D(r_shadow_texturepool, "attenuation2d", ATTEN2DSIZE, ATTEN2DSIZE, (unsigned char *)data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCELINEAR, -1, NULL);
        // 3D sphere texture
        if (r_shadow_texture3d.integer && vid.support.ext_texture_3d)
        {
@@ -1767,7 +1767,7 @@ static void R_Shadow_MakeTextures(void)
                        for (y = 0;y < ATTEN3DSIZE;y++)
                                for (x = 0;x < ATTEN3DSIZE;x++)
                                        data[(z*ATTEN3DSIZE+y)*ATTEN3DSIZE+x] = R_Shadow_MakeTextures_SamplePoint(((x + 0.5f) * (2.0f / ATTEN3DSIZE) - 1.0f) * (1.0f / 0.9375), ((y + 0.5f) * (2.0f / ATTEN3DSIZE) - 1.0f) * (1.0f / 0.9375), ((z + 0.5f) * (2.0f / ATTEN3DSIZE) - 1.0f) * (1.0f / 0.9375));
-               r_shadow_attenuation3dtexture = R_LoadTexture3D(r_shadow_texturepool, "attenuation3d", ATTEN3DSIZE, ATTEN3DSIZE, ATTEN3DSIZE, (unsigned char *)data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCELINEAR, NULL);
+               r_shadow_attenuation3dtexture = R_LoadTexture3D(r_shadow_texturepool, "attenuation3d", ATTEN3DSIZE, ATTEN3DSIZE, ATTEN3DSIZE, (unsigned char *)data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCELINEAR, -1, NULL);
        }
        else
                r_shadow_attenuation3dtexture = NULL;
@@ -1896,8 +1896,6 @@ void R_Shadow_ValidateCvars(void)
                Cvar_SetValueQuick(&gl_ext_stenciltwoside, 0);
 }
 
-static const r_vertexposition_t resetvertexposition[3];
-
 void R_Shadow_RenderMode_Begin(void)
 {
 #if 0
@@ -1913,8 +1911,8 @@ void R_Shadow_RenderMode_Begin(void)
                R_Shadow_MakeTextures();
 
        CHECKGLERROR
+       R_Mesh_ColorPointer(NULL, 0, 0);
        R_Mesh_ResetTextureState();
-       R_Mesh_PrepareVertices_Position(0, resetvertexposition, NULL);
        GL_BlendFunc(GL_ONE, GL_ZERO);
        GL_DepthRange(0, 1);
        GL_PolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);
@@ -1993,8 +1991,8 @@ void R_Shadow_RenderMode_Reset(void)
 #endif
        R_SetViewport(&r_refdef.view.viewport);
        GL_Scissor(r_shadow_lightscissor[0], r_shadow_lightscissor[1], r_shadow_lightscissor[2], r_shadow_lightscissor[3]);
+       R_Mesh_ColorPointer(NULL, 0, 0);
        R_Mesh_ResetTextureState();
-       R_Mesh_PrepareVertices_Position(0, resetvertexposition, NULL);
        GL_DepthRange(0, 1);
        GL_DepthTest(true);
        GL_DepthMask(false);
@@ -2092,7 +2090,7 @@ static void R_Shadow_MakeVSDCT(void)
                0,   0, 0x33, 0xFF, // +Z: <0, 0>, <0.5, 2.5>
                0,   0, 0x99, 0xFF, // -Z: <0, 0>, <1.5, 2.5>
        };
-       r_shadow_shadowmapvsdcttexture = R_LoadTextureCubeMap(r_shadow_texturepool, "shadowmapvsdct", 1, data, TEXTYPE_RGBA, TEXF_FORCENEAREST | TEXF_CLAMP | TEXF_ALPHA, NULL);
+       r_shadow_shadowmapvsdcttexture = R_LoadTextureCubeMap(r_shadow_texturepool, "shadowmapvsdct", 1, data, TEXTYPE_RGBA, TEXF_FORCENEAREST | TEXF_CLAMP | TEXF_ALPHA, -1, NULL);
 }
 
 static void R_Shadow_MakeShadowMap(int side, int size)
@@ -2304,7 +2302,7 @@ void R_Shadow_RenderMode_Lighting(qboolean stenciltest, qboolean transparent, qb
                        break;
                }
        }
-       //R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.array_passcolor4f, 0, 0);
+       R_Mesh_ColorPointer(rsurface.array_color4f, 0, 0);
        CHECKGLERROR
 }
 
@@ -2373,6 +2371,8 @@ void R_Shadow_RenderMode_DrawDeferredLight(qboolean stenciltest, qboolean shadow
                for (i = 0;i < 8;i++)
                        Matrix4x4_Transform(matrix, bboxpoints[i], vertex3f + i*3);
                CHECKGLERROR
+               R_Mesh_VertexPointer(vertex3f, 0, 0);
+               R_Mesh_ColorPointer(NULL, 0, 0);
                GL_ColorMask(1,1,1,1);
                GL_DepthMask(false);
                GL_DepthRange(0, 1);
@@ -2380,8 +2380,7 @@ void R_Shadow_RenderMode_DrawDeferredLight(qboolean stenciltest, qboolean shadow
                GL_DepthTest(true);
                qglDepthFunc(GL_GREATER);CHECKGLERROR
                GL_CullFace(r_refdef.view.cullface_back);
-               R_Mesh_PrepareVertices_Position_Arrays(8, vertex3f);
-               R_Mesh_Draw(0, 8, 0, 12, NULL, NULL, 0, bboxelements, NULL, 0);
+               R_Mesh_Draw(0, 8, 0, 12, NULL, bboxelements, 0, 0);
        }
 }
 
@@ -2428,146 +2427,35 @@ void R_Shadow_RenderMode_End(void)
        r_shadow_rendermode = R_SHADOW_RENDERMODE_NONE;
 }
 
-int bboxedges[12][2] =
-{
-       // top
-       {0, 1}, // +X
-       {0, 2}, // +Y
-       {1, 3}, // Y, +X
-       {2, 3}, // X, +Y
-       // bottom
-       {4, 5}, // +X
-       {4, 6}, // +Y
-       {5, 7}, // Y, +X
-       {6, 7}, // X, +Y
-       // verticals
-       {0, 4}, // +Z
-       {1, 5}, // X, +Z
-       {2, 6}, // Y, +Z
-       {3, 7}, // XY, +Z
-};
-
 qboolean R_Shadow_ScissorForBBox(const float *mins, const float *maxs)
 {
-       int i, ix1, iy1, ix2, iy2;
-       float x1, y1, x2, y2;
-       vec4_t v, v2;
-       float vertex[20][3];
-       int j, k;
-       vec4_t plane4f;
-       int numvertices;
-       float corner[8][4];
-       float dist[8];
-       int sign[8];
-       float f;
-
-       r_shadow_lightscissor[0] = r_refdef.view.viewport.x;
-       r_shadow_lightscissor[1] = r_refdef.view.viewport.y;
-       r_shadow_lightscissor[2] = r_refdef.view.viewport.width;
-       r_shadow_lightscissor[3] = r_refdef.view.viewport.height;
-
        if (!r_shadow_scissor.integer)
-               return false;
-
-       // if view is inside the light box, just say yes it's visible
-       if (BoxesOverlap(r_refdef.view.origin, r_refdef.view.origin, mins, maxs))
-               return false;
-
-       x1 = y1 = x2 = y2 = 0;
-
-       // transform all corners that are infront of the nearclip plane
-       VectorNegate(r_refdef.view.frustum[4].normal, plane4f);
-       plane4f[3] = r_refdef.view.frustum[4].dist;
-       numvertices = 0;
-       for (i = 0;i < 8;i++)
        {
-               Vector4Set(corner[i], (i & 1) ? maxs[0] : mins[0], (i & 2) ? maxs[1] : mins[1], (i & 4) ? maxs[2] : mins[2], 1);
-               dist[i] = DotProduct4(corner[i], plane4f);
-               sign[i] = dist[i] > 0;
-               if (!sign[i])
-               {
-                       VectorCopy(corner[i], vertex[numvertices]);
-                       numvertices++;
-               }
-       }
-       // if some points are behind the nearclip, add clipped edge points to make
-       // sure that the scissor boundary is complete
-       if (numvertices > 0 && numvertices < 8)
-       {
-               // add clipped edge points
-               for (i = 0;i < 12;i++)
-               {
-                       j = bboxedges[i][0];
-                       k = bboxedges[i][1];
-                       if (sign[j] != sign[k])
-                       {
-                               f = dist[j] / (dist[j] - dist[k]);
-                               VectorLerp(corner[j], f, corner[k], vertex[numvertices]);
-                               numvertices++;
-                       }
-               }
+               r_shadow_lightscissor[0] = r_refdef.view.viewport.x;
+               r_shadow_lightscissor[1] = r_refdef.view.viewport.y;
+               r_shadow_lightscissor[2] = r_refdef.view.viewport.width;
+               r_shadow_lightscissor[3] = r_refdef.view.viewport.height;
+               return false;
        }
 
-       // if we have no points to check, the light is behind the view plane
-       if (!numvertices)
-               return true;
-
-       // if we have some points to transform, check what screen area is covered
-       x1 = y1 = x2 = y2 = 0;
-       v[3] = 1.0f;
-       //Con_Printf("%i vertices to transform...\n", numvertices);
-       for (i = 0;i < numvertices;i++)
+       if(R_ScissorForBBox(mins, maxs, r_shadow_lightscissor))
        {
-               VectorCopy(vertex[i], v);
-               R_Viewport_TransformToScreen(&r_refdef.view.viewport, v, v2);
-               //Con_Printf("%.3f %.3f %.3f %.3f transformed to %.3f %.3f %.3f %.3f\n", v[0], v[1], v[2], v[3], v2[0], v2[1], v2[2], v2[3]);
-               if (i)
-               {
-                       if (x1 > v2[0]) x1 = v2[0];
-                       if (x2 < v2[0]) x2 = v2[0];
-                       if (y1 > v2[1]) y1 = v2[1];
-                       if (y2 < v2[1]) y2 = v2[1];
-               }
-               else
-               {
-                       x1 = x2 = v2[0];
-                       y1 = y2 = v2[1];
-               }
+               if(r_shadow_lightscissor[0] != r_refdef.view.viewport.x
+               || r_shadow_lightscissor[1] != r_refdef.view.viewport.y
+               || r_shadow_lightscissor[2] != r_refdef.view.viewport.width
+               || r_shadow_lightscissor[3] != r_refdef.view.viewport.height)
+                       r_refdef.stats.lights_scissored++;
+               return false;
        }
-
-       // now convert the scissor rectangle to integer screen coordinates
-       ix1 = (int)(x1 - 1.0f);
-       iy1 = vid.height - (int)(y2 - 1.0f);
-       ix2 = (int)(x2 + 1.0f);
-       iy2 = vid.height - (int)(y1 + 1.0f);
-       //Con_Printf("%f %f %f %f\n", x1, y1, x2, y2);
-
-       // clamp it to the screen
-       if (ix1 < r_refdef.view.viewport.x) ix1 = r_refdef.view.viewport.x;
-       if (iy1 < r_refdef.view.viewport.y) iy1 = r_refdef.view.viewport.y;
-       if (ix2 > r_refdef.view.viewport.x + r_refdef.view.viewport.width) ix2 = r_refdef.view.viewport.x + r_refdef.view.viewport.width;
-       if (iy2 > r_refdef.view.viewport.y + r_refdef.view.viewport.height) iy2 = r_refdef.view.viewport.y + r_refdef.view.viewport.height;
-
-       // if it is inside out, it's not visible
-       if (ix2 <= ix1 || iy2 <= iy1)
-               return true;
-
-       // the light area is visible, set up the scissor rectangle
-       r_shadow_lightscissor[0] = ix1;
-       r_shadow_lightscissor[1] = iy1;
-       r_shadow_lightscissor[2] = ix2 - ix1;
-       r_shadow_lightscissor[3] = iy2 - iy1;
-
-       r_refdef.stats.lights_scissored++;
-       return false;
+       else
+               return true; // invisible
 }
 
-static void R_Shadow_RenderLighting_Light_Vertex_Shading(int firstvertex, int numverts, const float *diffusecolor, const float *ambientcolor)
+static void R_Shadow_RenderLighting_Light_Vertex_Shading(int firstvertex, int numverts, int numtriangles, const int *element3i, const float *diffusecolor, const float *ambientcolor)
 {
-       int i;
-       const float *vertex3f;
-       const float *normal3f;
-       float *color4f;
+       const float *vertex3f = rsurface.vertex3f + 3 * firstvertex;
+       const float *normal3f = rsurface.normal3f + 3 * firstvertex;
+       float *color4f = rsurface.array_color4f + 4 * firstvertex;
        float dist, dot, distintensity, shadeintensity, v[3], n[3];
        switch (r_shadow_rendermode)
        {
@@ -2575,7 +2463,7 @@ static void R_Shadow_RenderLighting_Light_Vertex_Shading(int firstvertex, int nu
        case R_SHADOW_RENDERMODE_LIGHT_VERTEX2D1DATTEN:
                if (VectorLength2(diffusecolor) > 0)
                {
-                       for (i = 0, vertex3f = rsurface.batchvertex3f + 3*firstvertex, normal3f = rsurface.batchnormal3f + 3*firstvertex, color4f = rsurface.array_passcolor4f + 4 * firstvertex;i < numverts;i++, vertex3f += 3, normal3f += 3, color4f += 4)
+                       for (;numverts > 0;numverts--, vertex3f += 3, normal3f += 3, color4f += 4)
                        {
                                Matrix4x4_Transform(&rsurface.entitytolight, vertex3f, v);
                                Matrix4x4_Transform3x3(&rsurface.entitytolight, normal3f, n);
@@ -2597,7 +2485,7 @@ static void R_Shadow_RenderLighting_Light_Vertex_Shading(int firstvertex, int nu
                }
                else
                {
-                       for (i = 0, vertex3f = rsurface.batchvertex3f + 3*firstvertex, color4f = rsurface.array_passcolor4f + 4 * firstvertex;i < numverts;i++, vertex3f += 3, color4f += 4)
+                       for (;numverts > 0;numverts--, vertex3f += 3, color4f += 4)
                        {
                                VectorCopy(ambientcolor, color4f);
                                if (r_refdef.fogenabled)
@@ -2605,7 +2493,7 @@ static void R_Shadow_RenderLighting_Light_Vertex_Shading(int firstvertex, int nu
                                        float f;
                                        Matrix4x4_Transform(&rsurface.entitytolight, vertex3f, v);
                                        f = RSurf_FogVertex(vertex3f);
-                                       VectorScale(color4f + 4*i, f, color4f);
+                                       VectorScale(color4f, f, color4f);
                                }
                                color4f[3] = 1;
                        }
@@ -2614,7 +2502,7 @@ static void R_Shadow_RenderLighting_Light_Vertex_Shading(int firstvertex, int nu
        case R_SHADOW_RENDERMODE_LIGHT_VERTEX2DATTEN:
                if (VectorLength2(diffusecolor) > 0)
                {
-                       for (i = 0, vertex3f = rsurface.batchvertex3f + 3*firstvertex, normal3f = rsurface.batchnormal3f + 3*firstvertex, color4f = rsurface.array_passcolor4f + 4 * firstvertex;i < numverts;i++, vertex3f += 3, normal3f += 3, color4f += 4)
+                       for (;numverts > 0;numverts--, vertex3f += 3, normal3f += 3, color4f += 4)
                        {
                                Matrix4x4_Transform(&rsurface.entitytolight, vertex3f, v);
                                if ((dist = fabs(v[2])) < 1 && (distintensity = r_shadow_attentable[(int)(dist * ATTENTABLESIZE)]))
@@ -2647,7 +2535,7 @@ static void R_Shadow_RenderLighting_Light_Vertex_Shading(int firstvertex, int nu
                }
                else
                {
-                       for (i = 0, vertex3f = rsurface.batchvertex3f + 3*firstvertex, color4f = rsurface.array_passcolor4f + 4 * firstvertex;i < numverts;i++, vertex3f += 3, color4f += 4)
+                       for (;numverts > 0;numverts--, vertex3f += 3, color4f += 4)
                        {
                                Matrix4x4_Transform(&rsurface.entitytolight, vertex3f, v);
                                if ((dist = fabs(v[2])) < 1 && (distintensity = r_shadow_attentable[(int)(dist * ATTENTABLESIZE)]))
@@ -2671,7 +2559,7 @@ static void R_Shadow_RenderLighting_Light_Vertex_Shading(int firstvertex, int nu
        case R_SHADOW_RENDERMODE_LIGHT_VERTEX:
                if (VectorLength2(diffusecolor) > 0)
                {
-                       for (i = 0, vertex3f = rsurface.batchvertex3f + 3*firstvertex, normal3f = rsurface.batchnormal3f + 3*firstvertex, color4f = rsurface.array_passcolor4f + 4 * firstvertex;i < numverts;i++, vertex3f += 3, normal3f += 3, color4f += 4)
+                       for (;numverts > 0;numverts--, vertex3f += 3, normal3f += 3, color4f += 4)
                        {
                                Matrix4x4_Transform(&rsurface.entitytolight, vertex3f, v);
                                if ((dist = VectorLength(v)) < 1 && (distintensity = r_shadow_attentable[(int)(dist * ATTENTABLESIZE)]))
@@ -2705,7 +2593,7 @@ static void R_Shadow_RenderLighting_Light_Vertex_Shading(int firstvertex, int nu
                }
                else
                {
-                       for (i = 0, vertex3f = rsurface.batchvertex3f + 3*firstvertex, color4f = rsurface.array_passcolor4f + 4 * firstvertex;i < numverts;i++, vertex3f += 3, color4f += 4)
+                       for (;numverts > 0;numverts--, vertex3f += 3, color4f += 4)
                        {
                                Matrix4x4_Transform(&rsurface.entitytolight, vertex3f, v);
                                if ((dist = VectorLength(v)) < 1 && (distintensity = r_shadow_attentable[(int)(dist * ATTENTABLESIZE)]))
@@ -2732,23 +2620,21 @@ static void R_Shadow_RenderLighting_Light_Vertex_Shading(int firstvertex, int nu
        }
 }
 
-static void R_Shadow_RenderLighting_VisibleLighting(int texturenumsurfaces, const msurface_t **texturesurfacelist)
+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)
 {
        // used to display how many times a surface is lit for level design purposes
-       RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
-       R_Mesh_PrepareVertices_Generic_Arrays(rsurface.batchnumvertices, rsurface.batchvertex3f, NULL, NULL);
-       RSurf_DrawBatch();
+       R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 }
 
-static void R_Shadow_RenderLighting_Light_GLSL(int texturenumsurfaces, const msurface_t **texturesurfacelist, const vec3_t lightcolor, float ambientscale, float diffusescale, float specularscale)
+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_SetupShader_Surface(lightcolor, false, ambientscale, diffusescale, specularscale, RSURFPASS_RTLIGHT, texturenumsurfaces, texturesurfacelist);
+       R_SetupShader_Surface(lightcolor, false, ambientscale, diffusescale, specularscale, RSURFPASS_RTLIGHT);
        if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
        {
                qglDepthFunc(GL_EQUAL);CHECKGLERROR
        }
-       RSurf_DrawBatch();
+       R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
        if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
        {
                qglDepthFunc(GL_LEQUAL);CHECKGLERROR
@@ -2768,7 +2654,7 @@ static void R_Shadow_RenderLighting_Light_Vertex_Pass(int firstvertex, int numve
        float *c;
        int maxtriangles = 4096;
        static int newelements[4096*3];
-       R_Shadow_RenderLighting_Light_Vertex_Shading(firstvertex, numvertices, diffusecolor2, ambientcolor2);
+       R_Shadow_RenderLighting_Light_Vertex_Shading(firstvertex, numvertices, numtriangles, element3i, diffusecolor2, ambientcolor2);
        for (renders = 0;renders < 4;renders++)
        {
                stop = true;
@@ -2783,7 +2669,7 @@ static void R_Shadow_RenderLighting_Light_Vertex_Pass(int firstvertex, int numve
                // renders them at once
                for (i = 0, e = element3i;i < numtriangles;i++, e += 3)
                {
-                       if (VectorLength2(rsurface.array_passcolor4f + e[0] * 4) + VectorLength2(rsurface.array_passcolor4f + e[1] * 4) + VectorLength2(rsurface.array_passcolor4f + e[2] * 4) >= 0.01)
+                       if (VectorLength2(rsurface.array_color4f + e[0] * 4) + VectorLength2(rsurface.array_color4f + e[1] * 4) + VectorLength2(rsurface.array_color4f + e[2] * 4) >= 0.01)
                        {
                                if (newnumtriangles)
                                {
@@ -2806,7 +2692,7 @@ static void R_Shadow_RenderLighting_Light_Vertex_Pass(int firstvertex, int numve
                                newe += 3;
                                if (newnumtriangles >= maxtriangles)
                                {
-                                       R_Mesh_Draw(newfirstvertex, newlastvertex - newfirstvertex + 1, 0, newnumtriangles, newelements, NULL, 0, NULL, NULL, 0);
+                                       R_Mesh_Draw(newfirstvertex, newlastvertex - newfirstvertex + 1, 0, newnumtriangles, newelements, NULL, 0, 0);
                                        newnumtriangles = 0;
                                        newe = newelements;
                                        stop = false;
@@ -2815,7 +2701,7 @@ static void R_Shadow_RenderLighting_Light_Vertex_Pass(int firstvertex, int numve
                }
                if (newnumtriangles >= 1)
                {
-                       R_Mesh_Draw(newfirstvertex, newlastvertex - newfirstvertex + 1, 0, newnumtriangles, newelements, NULL, 0, NULL, NULL, 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
@@ -2826,7 +2712,7 @@ static void R_Shadow_RenderLighting_Light_Vertex_Pass(int firstvertex, int numve
                // handling of negative colors
                // (some old drivers even have improper handling of >1 color)
                stop = true;
-               for (i = 0, c = rsurface.array_passcolor4f + 4 * firstvertex;i < numvertices;i++, c += 4)
+               for (i = 0, c = rsurface.array_color4f + 4 * firstvertex;i < numvertices;i++, c += 4)
                {
                        if (c[0] > 1 || c[1] > 1 || c[2] > 1)
                        {
@@ -2844,7 +2730,7 @@ static void R_Shadow_RenderLighting_Light_Vertex_Pass(int firstvertex, int numve
        }
 }
 
-static void R_Shadow_RenderLighting_Light_Vertex(int texturenumsurfaces, const msurface_t **texturesurfacelist, const vec3_t lightcolor, float ambientscale, float diffusescale)
+static void R_Shadow_RenderLighting_Light_Vertex(int firstvertex, int numvertices, int numtriangles, const int *element3i, const vec3_t lightcolor, float ambientscale, float diffusescale)
 {
        // OpenGL 1.1 path (anything)
        float ambientcolorbase[3], diffusecolorbase[3];
@@ -2866,32 +2752,29 @@ static void R_Shadow_RenderLighting_Light_Vertex(int texturenumsurfaces, const m
        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];
-       RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | (diffusescale > 0 ? BATCHNEED_ARRAY_NORMAL : 0) | BATCHNEED_ARRAY_TEXCOORD, texturenumsurfaces, texturesurfacelist);
-       R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
-       R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.array_passcolor4f, 0, 0);
-       R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
        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_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, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
+               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_shadow_attenuation2dtexture);
                R_Mesh_TexMatrix(2, &rsurface.entitytoattenuationz);
                R_Mesh_TexCombine(2, GL_MODULATE, GL_MODULATE, 1, 1);
-               R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
+               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_shadow_attenuation2dtexture);
                R_Mesh_TexMatrix(1, &rsurface.entitytoattenuationxyz);
                R_Mesh_TexCombine(1, GL_MODULATE, GL_MODULATE, 1, 1);
-               R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
+               R_Mesh_TexCoordPointer(1, 3, rsurface.vertex3f, rsurface.vertex3f_bufferobject, rsurface.vertex3f_bufferoffset);
                break;
        case R_SHADOW_RENDERMODE_LIGHT_VERTEX:
                break;
@@ -2899,21 +2782,21 @@ static void R_Shadow_RenderLighting_Light_Vertex(int texturenumsurfaces, const m
                break;
        }
        //R_Mesh_TexBind(0, basetexture);
-       R_Shadow_RenderLighting_Light_Vertex_Pass(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.batchelement3i + 3*rsurface.batchfirsttriangle, diffusecolorbase, ambientcolorbase);
+       R_Shadow_RenderLighting_Light_Vertex_Pass(firstvertex, numvertices, numtriangles, element3i, diffusecolorbase, ambientcolorbase);
        if (dopants)
        {
                R_Mesh_TexBind(0, pantstexture);
-               R_Shadow_RenderLighting_Light_Vertex_Pass(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.batchelement3i + 3*rsurface.batchfirsttriangle, diffusecolorpants, ambientcolorpants);
+               R_Shadow_RenderLighting_Light_Vertex_Pass(firstvertex, numvertices, numtriangles, element3i, diffusecolorpants, ambientcolorpants);
        }
        if (doshirt)
        {
                R_Mesh_TexBind(0, shirttexture);
-               R_Shadow_RenderLighting_Light_Vertex_Pass(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.batchelement3i + 3*rsurface.batchfirsttriangle, diffusecolorshirt, ambientcolorshirt);
+               R_Shadow_RenderLighting_Light_Vertex_Pass(firstvertex, numvertices, numtriangles, element3i, diffusecolorshirt, ambientcolorshirt);
        }
 }
 
 extern cvar_t gl_lightmaps;
-void R_Shadow_RenderLighting(int texturenumsurfaces, const msurface_t **texturesurfacelist)
+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;
        qboolean negated;
@@ -2941,16 +2824,16 @@ void R_Shadow_RenderLighting(int texturenumsurfaces, const msurface_t **textures
        {
        case R_SHADOW_RENDERMODE_VISIBLELIGHTING:
                GL_DepthTest(!(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST) && !r_showdisabledepthtest.integer);
-               R_Shadow_RenderLighting_VisibleLighting(texturenumsurfaces, texturesurfacelist);
+               R_Shadow_RenderLighting_VisibleLighting(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
                break;
        case R_SHADOW_RENDERMODE_LIGHT_GLSL:
-               R_Shadow_RenderLighting_Light_GLSL(texturenumsurfaces, texturesurfacelist, lightcolor, ambientscale, diffusescale, specularscale);
+               R_Shadow_RenderLighting_Light_GLSL(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolor, ambientscale, diffusescale, specularscale);
                break;
        case R_SHADOW_RENDERMODE_LIGHT_VERTEX3DATTEN:
        case R_SHADOW_RENDERMODE_LIGHT_VERTEX2D1DATTEN:
        case R_SHADOW_RENDERMODE_LIGHT_VERTEX2DATTEN:
        case R_SHADOW_RENDERMODE_LIGHT_VERTEX:
-               R_Shadow_RenderLighting_Light_Vertex(texturenumsurfaces, texturesurfacelist, lightcolor, ambientscale, diffusescale);
+               R_Shadow_RenderLighting_Light_Vertex(firstvertex, numvertices, numtriangles, element3i + firsttriangle * 3, lightcolor, ambientscale, diffusescale);
                break;
        default:
                Con_Printf("R_Shadow_RenderLighting: unknown r_shadow_rendermode %i\n", r_shadow_rendermode);
@@ -3334,8 +3217,8 @@ void R_Shadow_DrawWorldShadow_ShadowMap(int numsurfaces, int *surfacelist, const
                        if (!mesh->sidetotals[r_shadow_shadowmapside])
                                continue;
             r_refdef.stats.lights_shadowtriangles += mesh->sidetotals[r_shadow_shadowmapside];
-            R_Mesh_PrepareVertices_Position(mesh->numverts, mesh->vertexposition, mesh->vertexpositionbuffer);
-            R_Mesh_Draw(0, mesh->numverts, mesh->sideoffsets[r_shadow_shadowmapside], mesh->sidetotals[r_shadow_shadowmapside], mesh->element3i, mesh->element3i_indexbuffer, mesh->element3i_bufferoffset, mesh->element3s, mesh->element3s_indexbuffer, mesh->element3s_bufferoffset);
+            R_Mesh_VertexPointer(mesh->vertex3f, mesh->vbo, mesh->vbooffset_vertex3f);
+            R_Mesh_Draw(0, mesh->numverts, mesh->sideoffsets[r_shadow_shadowmapside], mesh->sidetotals[r_shadow_shadowmapside], mesh->element3i, mesh->element3s, mesh->ebo3i, mesh->ebo3s);
         }
         CHECKGLERROR
     }
@@ -3367,13 +3250,13 @@ void R_Shadow_DrawWorldShadow_ShadowVolume(int numsurfaces, int *surfacelist, co
                for (;mesh;mesh = mesh->next)
                {
                        r_refdef.stats.lights_shadowtriangles += mesh->numtriangles;
-                       R_Mesh_PrepareVertices_Position(mesh->numverts, mesh->vertexposition, mesh->vertexpositionbuffer);
+                       R_Mesh_VertexPointer(mesh->vertex3f, mesh->vbo, mesh->vbooffset_vertex3f);
                        if (r_shadow_rendermode == R_SHADOW_RENDERMODE_ZPASS_STENCIL)
                        {
                                // increment stencil if frontface is infront of depthbuffer
                                GL_CullFace(r_refdef.view.cullface_back);
                                qglStencilOp(GL_KEEP, GL_KEEP, GL_INCR);CHECKGLERROR
-                               R_Mesh_Draw(0, mesh->numverts, 0, mesh->numtriangles, mesh->element3i, mesh->element3i_indexbuffer, mesh->element3i_bufferoffset, mesh->element3s, mesh->element3s_indexbuffer, mesh->element3s_bufferoffset);
+                               R_Mesh_Draw(0, mesh->numverts, 0, mesh->numtriangles, mesh->element3i, mesh->element3s, mesh->ebo3i, mesh->ebo3s);
                                // decrement stencil if backface is infront of depthbuffer
                                GL_CullFace(r_refdef.view.cullface_front);
                                qglStencilOp(GL_KEEP, GL_KEEP, GL_DECR);CHECKGLERROR
@@ -3383,12 +3266,12 @@ void R_Shadow_DrawWorldShadow_ShadowVolume(int numsurfaces, int *surfacelist, co
                                // 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, mesh->numverts, 0, mesh->numtriangles, mesh->element3i, mesh->element3i_indexbuffer, mesh->element3i_bufferoffset, mesh->element3s, mesh->element3s_indexbuffer, mesh->element3s_bufferoffset);
+                               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_refdef.view.cullface_back);
                                qglStencilOp(GL_KEEP, GL_INCR, GL_KEEP);CHECKGLERROR
                        }
-                       R_Mesh_Draw(0, mesh->numverts, 0, mesh->numtriangles, mesh->element3i, mesh->element3i_indexbuffer, mesh->element3i_bufferoffset, mesh->element3s, mesh->element3s_indexbuffer, mesh->element3s_bufferoffset);
+                       R_Mesh_Draw(0, mesh->numverts, 0, mesh->numtriangles, mesh->element3i, mesh->element3s, mesh->ebo3i, mesh->ebo3s);
                }
                CHECKGLERROR
        }
@@ -3998,6 +3881,7 @@ void R_Shadow_DrawPrepass(void)
        entity_render_t *ent;
 
        GL_AlphaTest(false);
+       R_Mesh_ColorPointer(NULL, 0, 0);
        R_Mesh_ResetTextureState();
        GL_DepthMask(true);
        GL_ColorMask(1,1,1,1);
@@ -4112,9 +3996,9 @@ void R_Shadow_PrepareLights(void)
                        r_shadow_prepass_width = vid.width;
                        r_shadow_prepass_height = vid.height;
                        r_shadow_prepassgeometrydepthtexture = R_LoadTextureShadowMap2D(r_shadow_texturepool, "prepassgeometrydepthmap", vid.width, vid.height, 24, false);
-                       r_shadow_prepassgeometrynormalmaptexture = R_LoadTexture2D(r_shadow_texturepool, "prepassgeometrynormalmap", vid.width, vid.height, NULL, TEXTYPE_COLORBUFFER, TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCENEAREST, NULL);
-                       r_shadow_prepasslightingdiffusetexture = R_LoadTexture2D(r_shadow_texturepool, "prepasslightingdiffuse", vid.width, vid.height, NULL, TEXTYPE_COLORBUFFER, TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCENEAREST, NULL);
-                       r_shadow_prepasslightingspeculartexture = R_LoadTexture2D(r_shadow_texturepool, "prepasslightingspecular", vid.width, vid.height, NULL, TEXTYPE_COLORBUFFER, TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCENEAREST, NULL);
+                       r_shadow_prepassgeometrynormalmaptexture = R_LoadTexture2D(r_shadow_texturepool, "prepassgeometrynormalmap", vid.width, vid.height, NULL, TEXTYPE_COLORBUFFER, TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCENEAREST, -1, NULL);
+                       r_shadow_prepasslightingdiffusetexture = R_LoadTexture2D(r_shadow_texturepool, "prepasslightingdiffuse", vid.width, vid.height, NULL, TEXTYPE_COLORBUFFER, TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCENEAREST, -1, NULL);
+                       r_shadow_prepasslightingspeculartexture = R_LoadTexture2D(r_shadow_texturepool, "prepasslightingspecular", vid.width, vid.height, NULL, TEXTYPE_COLORBUFFER, TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCENEAREST, -1, NULL);
 
                        // set up the geometry pass fbo (depth + normalmap)
                        qglGenFramebuffersEXT(1, &r_shadow_prepassgeometryfbo);CHECKGLERROR
@@ -4585,6 +4469,9 @@ void R_DrawModelShadows(void)
        //R_EntityMatrix(&identitymatrix);
        //R_Mesh_ResetTextureState();
        R_ResetViewRendering2D();
+       R_Mesh_VertexPointer(r_screenvertex3f, 0, 0);
+       R_Mesh_ColorPointer(NULL, 0, 0);
+       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);
@@ -4601,9 +4488,7 @@ void R_DrawModelShadows(void)
        qglStencilFunc(GL_NOTEQUAL, 128, 255);CHECKGLERROR
 
        // apply the blend to the shadowed areas
-       R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, NULL);
-       R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
-       R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
+       R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, polygonelement3s, 0, 0);
 
        // restore the viewport
        R_SetViewport(&r_refdef.view.viewport);
@@ -4635,14 +4520,14 @@ void R_BeginCoronaQuery(rtlight_t *rtlight, float scale, qboolean usequery)
                qglBeginQueryARB(GL_SAMPLES_PASSED_ARB, rtlight->corona_queryindex_allpixels);
                qglDepthFunc(GL_ALWAYS);
                R_CalcSprite_Vertex3f(vertex3f, centerorigin, r_refdef.view.right, r_refdef.view.up, scale, -scale, -scale, scale);
-               R_Mesh_PrepareVertices_Position_Arrays(4, vertex3f);
-               R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
+               R_Mesh_VertexPointer(vertex3f, 0, 0);
+               R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, polygonelement3s, 0, 0);
                qglEndQueryARB(GL_SAMPLES_PASSED_ARB);
                qglDepthFunc(GL_LEQUAL);
                qglBeginQueryARB(GL_SAMPLES_PASSED_ARB, rtlight->corona_queryindex_visiblepixels);
                R_CalcSprite_Vertex3f(vertex3f, rtlight->shadoworigin, r_refdef.view.right, r_refdef.view.up, scale, -scale, -scale, scale);
-               R_Mesh_PrepareVertices_Position_Arrays(4, vertex3f);
-               R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
+               R_Mesh_VertexPointer(vertex3f, 0, 0);
+               R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, polygonelement3s, 0, 0);
                qglEndQueryARB(GL_SAMPLES_PASSED_ARB);
                CHECKGLERROR
        }
@@ -4734,6 +4619,7 @@ void R_Shadow_DrawCoronas(void)
                GL_DepthRange(0, 1);
                GL_PolygonOffset(0, 0);
                GL_DepthTest(true);
+               R_Mesh_ColorPointer(NULL, 0, 0);
                R_Mesh_ResetTextureState();
                R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
        }