]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_rsurf.c
moved a number of msurface_t fields to a separate msurface_lightmapinfo_t structure...
[xonotic/darkplaces.git] / gl_rsurf.c
index 007e6bbae707b466e9b1a16200dc2ea8d29a1034..f4e8c468d5c1f7f9cbf142e44626841e1d500864 100644 (file)
@@ -24,15 +24,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #define MAX_LIGHTMAP_SIZE 256
 
-static unsigned int intblocklights[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE*3]; // LordHavoc: *3 for colored lighting
-static float floatblocklights[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE*3]; // LordHavoc: *3 for colored lighting
-
-static qbyte templight[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE*4];
-
 cvar_t r_ambient = {0, "r_ambient", "0"};
 cvar_t r_drawportals = {0, "r_drawportals", "0"};
 cvar_t r_testvis = {0, "r_testvis", "0"};
-cvar_t r_floatbuildlightmap = {0, "r_floatbuildlightmap", "0"};
 cvar_t r_detailtextures = {CVAR_SAVE, "r_detailtextures", "1"};
 cvar_t r_surfaceworldnode = {0, "r_surfaceworldnode", "0"};
 cvar_t r_drawcollisionbrushes_polygonfactor = {0, "r_drawcollisionbrushes_polygonfactor", "-1"};
@@ -58,154 +52,79 @@ Combine and scale multiple lightmaps into the 8.8 format in blocklights
 */
 static void R_BuildLightMap (const entity_render_t *ent, msurface_t *surface)
 {
-       if (!r_floatbuildlightmap.integer)
+       int smax, tmax, i, j, size, size3, maps, stride, l;
+       unsigned int *bl, scale;
+       qbyte *lightmap, *out, *stain;
+       static unsigned int intblocklights[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE*3]; // LordHavoc: *3 for colored lighting
+       static qbyte templight[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE*4];
+
+       // update cached lighting info
+       surface->cached_dlight = 0;
+
+       smax = (surface->lightmapinfo->extents[0]>>4)+1;
+       tmax = (surface->lightmapinfo->extents[1]>>4)+1;
+       size = smax*tmax;
+       size3 = size*3;
+       lightmap = surface->lightmapinfo->samples;
+
+// set to full bright if no light data
+       bl = intblocklights;
+       if (!ent->model->brushq1.lightdata)
        {
-               int smax, tmax, i, j, size, size3, maps, stride, l;
-               unsigned int *bl, scale;
-               qbyte *lightmap, *out, *stain;
-
-               // update cached lighting info
-               surface->cached_dlight = 0;
-
-               smax = (surface->extents[0]>>4)+1;
-               tmax = (surface->extents[1]>>4)+1;
-               size = smax*tmax;
-               size3 = size*3;
-               lightmap = surface->samples;
-
-       // set to full bright if no light data
-               bl = intblocklights;
-               if (!ent->model->brushq1.lightdata)
-               {
-                       for (i = 0;i < size3;i++)
-                               bl[i] = 255*256;
-               }
-               else
-               {
-       // clear to no light
-                       memset(bl, 0, size*3*sizeof(unsigned int));
-
-       // add all the lightmaps
-                       if (lightmap)
-                       {
-                               bl = intblocklights;
-                               for (maps = 0;maps < MAXLIGHTMAPS && surface->styles[maps] != 255;maps++, lightmap += size3)
-                                       for (scale = d_lightstylevalue[surface->styles[maps]], i = 0;i < size3;i++)
-                                               bl[i] += lightmap[i] * scale;
-                       }
-               }
-
-               stain = surface->stainsamples;
-               bl = intblocklights;
-               out = templight;
-               // the >> 16 shift adjusts down 8 bits to account for the stainmap
-               // scaling, and remaps the 0-65536 (2x overbright) to 0-256, it will
-               // be doubled during rendering to achieve 2x overbright
-               // (0 = 0.0, 128 = 1.0, 256 = 2.0)
-               if (ent->model->brushq1.lightmaprgba)
-               {
-                       stride = (surface->lightmaptexturestride - smax) * 4;
-                       for (i = 0;i < tmax;i++, out += stride)
-                       {
-                               for (j = 0;j < smax;j++)
-                               {
-                                       l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255);
-                                       l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255);
-                                       l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255);
-                                       *out++ = 255;
-                               }
-                       }
-               }
-               else
-               {
-                       stride = (surface->lightmaptexturestride - smax) * 3;
-                       for (i = 0;i < tmax;i++, out += stride)
-                       {
-                               for (j = 0;j < smax;j++)
-                               {
-                                       l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255);
-                                       l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255);
-                                       l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255);
-                               }
-                       }
-               }
-
-               R_UpdateTexture(surface->lightmaptexture, templight);
+               for (i = 0;i < size3;i++)
+                       bl[i] = 255*256;
        }
        else
        {
-               int smax, tmax, i, j, size, size3, maps, stride, l;
-               float *bl, scale;
-               qbyte *lightmap, *out, *stain;
-
-               // update cached lighting info
-               surface->cached_dlight = 0;
-
-               smax = (surface->extents[0]>>4)+1;
-               tmax = (surface->extents[1]>>4)+1;
-               size = smax*tmax;
-               size3 = size*3;
-               lightmap = surface->samples;
-
-       // set to full bright if no light data
-               bl = floatblocklights;
-               if (!ent->model->brushq1.lightdata)
-               {
-                       for (i = 0;i < size3;i++)
-                               bl[i] = 255*256;
-               }
-               else
-               {
-                       memset(bl, 0, size*3*sizeof(float));
+// clear to no light
+               memset(bl, 0, size*3*sizeof(unsigned int));
 
-                       // add all the lightmaps
-                       if (lightmap)
-                       {
-                               bl = floatblocklights;
-                               for (maps = 0;maps < MAXLIGHTMAPS && surface->styles[maps] != 255;maps++, lightmap += size3)
-                                       for (scale = d_lightstylevalue[surface->styles[maps]], i = 0;i < size3;i++)
-                                               bl[i] += lightmap[i] * scale;
-                       }
+// add all the lightmaps
+               if (lightmap)
+               {
+                       bl = intblocklights;
+                       for (maps = 0;maps < MAXLIGHTMAPS && surface->lightmapinfo->styles[maps] != 255;maps++, lightmap += size3)
+                               for (scale = d_lightstylevalue[surface->lightmapinfo->styles[maps]], i = 0;i < size3;i++)
+                                       bl[i] += lightmap[i] * scale;
                }
+       }
 
-               stain = surface->stainsamples;
-               bl = floatblocklights;
-               out = templight;
-               // this scaling adjusts down 8 bits to account for the stainmap
-               // scaling, and remaps the 0.0-2.0 (2x overbright) to 0-256, it will
-               // be doubled during rendering to achieve 2x overbright
-               // (0 = 0.0, 128 = 1.0, 256 = 2.0)
-               scale = 1.0f / (1 << 16);
-               if (ent->model->brushq1.lightmaprgba)
+       stain = surface->lightmapinfo->stainsamples;
+       bl = intblocklights;
+       out = templight;
+       // the >> 16 shift adjusts down 8 bits to account for the stainmap
+       // scaling, and remaps the 0-65536 (2x overbright) to 0-256, it will
+       // be doubled during rendering to achieve 2x overbright
+       // (0 = 0.0, 128 = 1.0, 256 = 2.0)
+       if (ent->model->brushq1.lightmaprgba)
+       {
+               stride = (surface->lightmapinfo->lightmaptexturestride - smax) * 4;
+               for (i = 0;i < tmax;i++, out += stride)
                {
-                       stride = (surface->lightmaptexturestride - smax) * 4;
-                       for (i = 0;i < tmax;i++, out += stride)
+                       for (j = 0;j < smax;j++)
                        {
-                               for (j = 0;j < smax;j++)
-                               {
-                                       l = *bl++ * *stain++ * scale;*out++ = min(l, 255);
-                                       l = *bl++ * *stain++ * scale;*out++ = min(l, 255);
-                                       l = *bl++ * *stain++ * scale;*out++ = min(l, 255);
-                                       *out++ = 255;
-                               }
+                               l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255);
+                               l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255);
+                               l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255);
+                               *out++ = 255;
                        }
                }
-               else
+       }
+       else
+       {
+               stride = (surface->lightmapinfo->lightmaptexturestride - smax) * 3;
+               for (i = 0;i < tmax;i++, out += stride)
                {
-                       stride = (surface->lightmaptexturestride - smax) * 3;
-                       for (i = 0;i < tmax;i++, out += stride)
+                       for (j = 0;j < smax;j++)
                        {
-                               for (j = 0;j < smax;j++)
-                               {
-                                       l = *bl++ * *stain++ * scale;*out++ = min(l, 255);
-                                       l = *bl++ * *stain++ * scale;*out++ = min(l, 255);
-                                       l = *bl++ * *stain++ * scale;*out++ = min(l, 255);
-                               }
+                               l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255);
+                               l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255);
+                               l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255);
                        }
                }
-
-               R_UpdateTexture(surface->lightmaptexture, templight);
        }
+
+       R_UpdateTexture(surface->lightmaptexture, templight);
 }
 
 void R_StainNode (mnode_t *node, model_t *model, const vec3_t origin, float radius, const float fcolor[8])
@@ -251,13 +170,13 @@ loc0:
 
        for (surface = model->brush.data_surfaces + node->firstsurface, endsurface = surface + node->numsurfaces;surface < endsurface;surface++)
        {
-               if (surface->stainsamples)
+               if (surface->lightmapinfo->stainsamples)
                {
-                       smax = (surface->extents[0] >> 4) + 1;
-                       tmax = (surface->extents[1] >> 4) + 1;
+                       smax = (surface->lightmapinfo->extents[0] >> 4) + 1;
+                       tmax = (surface->lightmapinfo->extents[1] >> 4) + 1;
 
-                       impacts = DotProduct (impact, surface->texinfo->vecs[0]) + surface->texinfo->vecs[0][3] - surface->texturemins[0];
-                       impactt = DotProduct (impact, surface->texinfo->vecs[1]) + surface->texinfo->vecs[1][3] - surface->texturemins[1];
+                       impacts = DotProduct (impact, surface->lightmapinfo->texinfo->vecs[0]) + surface->lightmapinfo->texinfo->vecs[0][3] - surface->lightmapinfo->texturemins[0];
+                       impactt = DotProduct (impact, surface->lightmapinfo->texinfo->vecs[1]) + surface->lightmapinfo->texinfo->vecs[1][3] - surface->lightmapinfo->texturemins[1];
 
                        s = bound(0, impacts, smax * 16) - impacts;
                        t = bound(0, impactt, tmax * 16) - impactt;
@@ -269,7 +188,7 @@ loc0:
                        for (s = 0, i = impacts; s < smax; s++, i -= 16)
                                sdtable[s] = i * i + dist2;
 
-                       bl = surface->stainsamples;
+                       bl = surface->lightmapinfo->stainsamples;
                        smax3 = smax * 3;
                        stained = false;
 
@@ -337,7 +256,7 @@ void R_Stain (const vec3_t origin, float radius, int cr1, int cg1, int cb1, int
        entity_render_t *ent;
        model_t *model;
        vec3_t org;
-       if (r_refdef.worldmodel == NULL || !r_refdef.worldmodel->brush.data_nodes)
+       if (r_refdef.worldmodel == NULL || !r_refdef.worldmodel->brush.data_nodes || !r_refdef.worldmodel->brushq1.lightdata)
                return;
        fcolor[0] = cr1;
        fcolor[1] = cg1;
@@ -376,55 +295,78 @@ void R_Stain (const vec3_t origin, float radius, int cr1, int cg1, int cb1, int
 =============================================================
 */
 
-static float *RSurf_GetVertexPointer(const entity_render_t *ent, const msurface_t *surface)
+static void RSurf_DeformVertices(const entity_render_t *ent, const texture_t *texture, const msurface_t *surface, const vec3_t modelorg)
 {
-       if (surface->texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
+       int i, j;
+       float center[3], forward[3], right[3], up[3], v[4][3];
+       matrix4x4_t matrix1, imatrix1;
+       if (texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE2)
        {
-               texture_t *texture = surface->texture;
-               int i, j;
-               float center[3], center2[3], forward[3], right[3], up[3], v[4][3];
-               matrix4x4_t matrix1, imatrix1;
-               R_Mesh_Matrix(&r_identitymatrix);
                // a single autosprite surface can contain multiple sprites...
+               VectorClear(forward);
+               VectorClear(right);
+               VectorSet(up, 0, 0, 1);
                for (j = 0;j < surface->mesh.num_vertices - 3;j += 4)
                {
                        VectorClear(center);
                        for (i = 0;i < 4;i++)
                                VectorAdd(center, surface->mesh.data_vertex3f + (j+i) * 3, center);
                        VectorScale(center, 0.25f, center);
-                       Matrix4x4_Transform(&ent->matrix, center, center2);
                        // FIXME: calculate vectors from triangle edges instead of using texture vectors as an easy way out?
                        Matrix4x4_FromVectors(&matrix1, surface->mesh.data_normal3f + j*3, surface->mesh.data_svector3f + j*3, surface->mesh.data_tvector3f + j*3, center);
                        Matrix4x4_Invert_Simple(&imatrix1, &matrix1);
                        for (i = 0;i < 4;i++)
                                Matrix4x4_Transform(&imatrix1, surface->mesh.data_vertex3f + (j+i)*3, v[i]);
-                       if (texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE2)
-                       {
-                               forward[0] = r_vieworigin[0] - center2[0];
-                               forward[1] = r_vieworigin[1] - center2[1];
-                               forward[2] = 0;
-                               VectorNormalize(forward);
-                               right[0] = forward[1];
-                               right[1] = -forward[0];
-                               right[2] = 0;
-                               up[0] = 0;
-                               up[1] = 0;
-                               up[2] = 1;
-                       }
-                       else
-                       {
-                               VectorCopy(r_viewforward, forward);
-                               VectorCopy(r_viewright, right);
-                               VectorCopy(r_viewup, up);
-                       }
+                       forward[0] = modelorg[0] - center[0];
+                       forward[1] = modelorg[1] - center[1];
+                       VectorNormalize(forward);
+                       right[0] = forward[1];
+                       right[1] = -forward[0];
+                       for (i = 0;i < 4;i++)
+                               VectorMAMAMAM(1, center, v[i][0], forward, v[i][1], right, v[i][2], up, varray_vertex3f + (i+j) * 3);
+               }
+       }
+       else if (texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE)
+       {
+               Matrix4x4_Transform(&ent->inversematrix, r_viewforward, forward);
+               Matrix4x4_Transform(&ent->inversematrix, r_viewright, right);
+               Matrix4x4_Transform(&ent->inversematrix, r_viewup, up);
+               // a single autosprite surface can contain multiple sprites...
+               for (j = 0;j < surface->mesh.num_vertices - 3;j += 4)
+               {
+                       VectorClear(center);
                        for (i = 0;i < 4;i++)
-                               VectorMAMAMAM(1, center2, v[i][0], forward, v[i][1], right, v[i][2], up, varray_vertex3f + (i+j) * 3);
+                               VectorAdd(center, surface->mesh.data_vertex3f + (j+i) * 3, center);
+                       VectorScale(center, 0.25f, center);
+                       // FIXME: calculate vectors from triangle edges instead of using texture vectors as an easy way out?
+                       Matrix4x4_FromVectors(&matrix1, surface->mesh.data_normal3f + j*3, surface->mesh.data_svector3f + j*3, surface->mesh.data_tvector3f + j*3, center);
+                       Matrix4x4_Invert_Simple(&imatrix1, &matrix1);
+                       for (i = 0;i < 4;i++)
+                               Matrix4x4_Transform(&imatrix1, surface->mesh.data_vertex3f + (j+i)*3, v[i]);
+                       for (i = 0;i < 4;i++)
+                               VectorMAMAMAM(1, center, v[i][0], forward, v[i][1], right, v[i][2], up, varray_vertex3f + (i+j) * 3);
                }
+       }
+       else
+               memcpy(varray_vertex3f, surface->mesh.data_vertex3f, sizeof(float[3]) * surface->mesh.num_vertices);
+}
+
+// any sort of deformvertices call is *VERY* rare, so this must be optimized
+// to skip deformvertices quickly!
+#if 1
+#define RSurf_GetVertexPointer(ent, texture, surface, modelorg) ((texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2)) ? (RSurf_DeformVertices(ent, texture, surface, modelorg), varray_vertex3f) : surface->mesh.data_vertex3f)
+#else
+static float *RSurf_GetVertexPointer(const entity_render_t *ent, const texture_t *texture, const msurface_t *surface, const vec3_t modelorg)
+{
+       if (texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
+       {
+               RSurf_DeformVertices(ent, texture, surface, modelorg);
                return varray_vertex3f;
        }
        else
                return surface->mesh.data_vertex3f;
 }
+#endif
 
 void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
 {
@@ -462,7 +404,7 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
 {
        int i;
        int texturesurfaceindex;
-       const float *v;
+       const float *v, *vertex3f;
        float *c;
        float diff[3];
        float f, r, g, b, a, base, colorscale;
@@ -489,20 +431,14 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                qglDisable(GL_CULL_FACE);
                GL_Color(1, 1, 1, 1);
                memset(&m, 0, sizeof(m));
+               R_Mesh_State(&m);
                for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                {
                        surface = texturesurfacelist[texturesurfaceindex];
-                       m.tex[0] = R_GetTexture(surface->lightmaptexture);
-                       m.pointer_texcoord[0] = surface->mesh.data_texcoordlightmap2f;
-                       if (surface->lightmaptexture)
-                       {
-                               GL_Color(1, 1, 1, 1);
-                               m.pointer_color = NULL;
-                       }
-                       else
-                               m.pointer_color = surface->mesh.data_lightmapcolor4f;
-                       m.pointer_vertex = surface->mesh.data_vertex3f;
-                       R_Mesh_State(&m);
+                       R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
+                       R_Mesh_TexCoordPointer(0, 2, surface->mesh.data_texcoordlightmap2f);
+                       R_Mesh_ColorPointer(surface->lightmaptexture ? NULL : surface->mesh.data_lightmapcolor4f);
+                       R_Mesh_VertexPointer(surface->mesh.data_vertex3f);
                        GL_LockArrays(0, surface->mesh.num_vertices);
                        R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
                        GL_LockArrays(0, 0);
@@ -551,11 +487,11 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                        GL_DepthMask(true);
                        GL_DepthTest(true);
                        memset(&m, 0, sizeof(m));
+                       R_Mesh_State(&m);
                        for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                        {
                                surface = texturesurfacelist[texturesurfaceindex];
-                               m.pointer_vertex = surface->mesh.data_vertex3f;
-                               R_Mesh_State(&m);
+                               R_Mesh_VertexPointer(surface->mesh.data_vertex3f);
                                GL_LockArrays(0, surface->mesh.num_vertices);
                                R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
                                GL_LockArrays(0, 0);
@@ -574,7 +510,9 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                m.texcombinergb[1] = GL_REPLACE;
                Matrix4x4_CreateFromQuakeEntity(&m.texmatrix[0], 0, 0, 0, 0, 0, 0, r_watershader.value);
                m.texmatrix[1] = r_surf_waterscrollmatrix;
+               R_Mesh_State(&m);
 
+               GL_Color(1, 1, 1, texture->currentalpha);
                GL_ActiveTexture(0);
                qglTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D);
                GL_ActiveTexture(1);
@@ -586,10 +524,9 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                {
                        surface = texturesurfacelist[texturesurfaceindex];
-                       m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
-                       m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
-                       m.pointer_texcoord[1] = surface->mesh.data_texcoordtexture2f;
-                       R_Mesh_State(&m);
+                       R_Mesh_VertexPointer(RSurf_GetVertexPointer(ent, texture, surface, modelorg));
+                       R_Mesh_TexCoordPointer(0, 2, surface->mesh.data_texcoordtexture2f);
+                       R_Mesh_TexCoordPointer(1, 2, surface->mesh.data_texcoordtexture2f);
                        GL_LockArrays(0, surface->mesh.num_vertices);
                        R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
                        GL_LockArrays(0, 0);
@@ -605,7 +542,7 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                dobase = true;
                dolightmap = !(texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT);
                doambient = r_ambient.value >= (1/64.0f);
-               dodetail = texture->skin.detail != NULL && !(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT);
+               dodetail = r_detailtextures.integer && texture->skin.detail != NULL && !(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT);
                doglow = texture->skin.glow != NULL;
                dofogpass = fogenabled && !(texture->currentmaterialflags & MATERIALFLAG_ADD);
                fogallpasses = fogenabled && !(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT);
@@ -620,25 +557,37 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                                        m.texmatrix[1] = r_surf_waterscrollmatrix;
                                m.texrgbscale[1] = 2;
                                m.pointer_color = varray_color4f;
+                               R_Mesh_State(&m);
                                colorscale = 1;
                                r = ent->colormod[0] * colorscale;
                                g = ent->colormod[1] * colorscale;
                                b = ent->colormod[2] * colorscale;
                                a = texture->currentalpha;
                                base = r_ambient.value * (1.0f / 64.0f);
+                               // q3bsp has no lightmap updates, so the lightstylevalue that
+                               // would normally be baked into the lightmaptexture must be
+                               // applied to the color
+                               if (ent->model->brushq1.lightdata)
+                               {
+                                       float scale = d_lightstylevalue[0] * (1.0f / 128.0f);
+                                       r *= scale;
+                                       g *= scale;
+                                       b *= scale;
+                               }
                                for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                {
                                        surface = texturesurfacelist[texturesurfaceindex];
-                                       m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
-                                       m.pointer_texcoord[0] = surface->mesh.data_texcoordlightmap2f;
-                                       m.pointer_texcoord[1] = surface->mesh.data_texcoordtexture2f;
+                                       vertex3f = RSurf_GetVertexPointer(ent, texture, surface, modelorg);
+                                       R_Mesh_VertexPointer(vertex3f);
+                                       R_Mesh_TexCoordPointer(0, 2, surface->mesh.data_texcoordlightmap2f);
+                                       R_Mesh_TexCoordPointer(1, 2, surface->mesh.data_texcoordtexture2f);
                                        if (surface->lightmaptexture)
                                        {
-                                               m.tex[0] = R_GetTexture(surface->lightmaptexture);
+                                               R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
                                                if (fogallpasses)
                                                {
-                                                       m.pointer_color = varray_color4f;
-                                                       for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
+                                                       R_Mesh_ColorPointer(varray_color4f);
+                                                       for (i = 0, v = vertex3f, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
                                                        {
                                                                VectorSubtract(v, modelorg, diff);
                                                                f = 1 - exp(fogdensity/DotProduct(diff, diff));
@@ -650,89 +599,39 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                                                }
                                                else
                                                {
-                                                       m.pointer_color = NULL;
+                                                       R_Mesh_ColorPointer(NULL);
                                                        GL_Color(r, g, b, a);
                                                }
                                        }
                                        else
                                        {
-                                               m.tex[0] = R_GetTexture(r_texture_white);
-                                               m.pointer_color = varray_color4f;
-                                               if (surface->styles[0] != 255)
+                                               R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
+                                               R_Mesh_ColorPointer(varray_color4f);
+                                               if (surface->mesh.data_lightmapcolor4f)
                                                {
-                                                       for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
+                                                       for (i = 0, c = varray_color4f;i < surface->mesh.num_vertices;i++, c += 4)
                                                        {
-                                                               c[0] = 0;
-                                                               c[1] = 0;
-                                                               c[2] = 0;
-                                                               if (surface->styles[0] != 255)
-                                                               {
-                                                                       if (surface->mesh.data_lightmapcolor4f)
-                                                                       {
-                                                                               float scale = d_lightstylevalue[surface->styles[0]] * (1.0f / 128.0f);
-                                                                               VectorMA(c, scale, surface->mesh.data_lightmapcolor4f + i*4, c);
-                                                                       }
-                                                                       else if (surface->mesh.data_lightmapoffsets)
-                                                                       {
-                                                                               const qbyte *lm = surface->samples + surface->mesh.data_lightmapoffsets[i];
-                                                                               float scale = d_lightstylevalue[surface->styles[0]] * (1.0f / 32768.0f);
-                                                                               VectorMA(c, scale, lm, c);
-                                                                               if (surface->styles[1] != 255)
-                                                                               {
-                                                                                       int size3 = ((surface->extents[0]>>4)+1)*((surface->extents[1]>>4)+1)*3;
-                                                                                       lm += size3;
-                                                                                       scale = d_lightstylevalue[surface->styles[1]] * (1.0f / 32768.0f);
-                                                                                       VectorMA(c, scale, lm, c);
-                                                                                       if (surface->styles[2] != 255)
-                                                                                       {
-                                                                                               lm += size3;
-                                                                                               scale = d_lightstylevalue[surface->styles[2]] * (1.0f / 32768.0f);
-                                                                                               VectorMA(c, scale, lm, c);
-                                                                                               if (surface->styles[3] != 255)
-                                                                                               {
-                                                                                                       lm += size3;
-                                                                                                       scale = d_lightstylevalue[surface->styles[3]] * (1.0f / 32768.0f);
-                                                                                                       VectorMA(c, scale, lm, c);
-                                                                                               }
-                                                                                       }
-                                                                               }
-                                                                       }
-                                                               }
-                                                               c[0] *= r;
-                                                               c[1] *= g;
-                                                               c[2] *= b;
-                                                               if (fogallpasses)
+                                                               c[0] = surface->mesh.data_lightmapcolor4f[i*4+0] * r;
+                                                               c[1] = surface->mesh.data_lightmapcolor4f[i*4+1] * g;
+                                                               c[2] = surface->mesh.data_lightmapcolor4f[i*4+2] * b;
+                                                               c[3] = surface->mesh.data_lightmapcolor4f[i*4+3] * a;
+                                                       }
+                                                       if (fogallpasses)
+                                                       {
+                                                               for (i = 0, v = vertex3f, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
                                                                {
                                                                        VectorSubtract(v, modelorg, diff);
                                                                        f = 1 - exp(fogdensity/DotProduct(diff, diff));
                                                                        VectorScale(c, f, c);
                                                                }
-                                                               if (surface->mesh.data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
-                                                                       c[3] = surface->mesh.data_lightmapcolor4f[i*4+3] * a;
-                                                               else
-                                                                       c[3] = a;
                                                        }
                                                }
                                                else
                                                {
-                                                       if (surface->mesh.data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
-                                                       {
-                                                               for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
-                                                               {
-                                                                       c[0] = 0;
-                                                                       c[1] = 0;
-                                                                       c[2] = 0;
-                                                                       c[3] = surface->mesh.data_lightmapcolor4f[i*4+3] * a;
-                                                               }
-                                                       }
-                                                       else
-                                                       {
-                                                               m.pointer_color = NULL;
-                                                               GL_Color(0, 0, 0, a);
-                                                       }
+                                                       R_Mesh_ColorPointer(NULL);
+                                                       GL_Color(0, 0, 0, a);
                                                }
                                        }
-                                       R_Mesh_State(&m);
                                        GL_LockArrays(0, surface->mesh.num_vertices);
                                        R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
                                        GL_LockArrays(0, 0);
@@ -753,51 +652,57 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                                        m.texrgbscale[0] = 4;
                                        colorscale *= 0.25f;
                                }
+                               R_Mesh_State(&m);
                                r = ent->colormod[0] * colorscale;
                                g = ent->colormod[1] * colorscale;
                                b = ent->colormod[2] * colorscale;
                                a = texture->currentalpha;
                                if (dolightmap)
                                {
+                                       // q3bsp has no lightmap updates, so the lightstylevalue that
+                                       // would normally be baked into the lightmaptexture must be
+                                       // applied to the color
+                                       if (!ent->model->brushq1.lightdata)
+                                       {
+                                               float scale = d_lightstylevalue[0] * (1.0f / 128.0f);
+                                               r *= scale;
+                                               g *= scale;
+                                               b *= scale;
+                                       }
                                        for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                        {
                                                surface = texturesurfacelist[texturesurfaceindex];
-                                               m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
-                                               m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
-                                               for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
+                                               vertex3f = RSurf_GetVertexPointer(ent, texture, surface, modelorg);
+                                               R_Mesh_VertexPointer(vertex3f);
+                                               R_Mesh_TexCoordPointer(0, 2, surface->mesh.data_texcoordtexture2f);
+                                               for (i = 0, v = vertex3f, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
                                                {
                                                        c[0] = 0;
                                                        c[1] = 0;
                                                        c[2] = 0;
-                                                       if (surface->styles[0] != 255)
+                                                       if (surface->mesh.data_lightmapcolor4f)
+                                                               VectorCopy(surface->mesh.data_lightmapcolor4f + i*4, c);
+                                                       else if (surface->lightmapinfo)
                                                        {
-                                                               if (surface->mesh.data_lightmapcolor4f)
-                                                               {
-                                                                       float scale = d_lightstylevalue[surface->styles[0]] * (1.0f / 128.0f);
-                                                                       VectorMA(c, scale, surface->mesh.data_lightmapcolor4f + i*4, c);
-                                                               }
-                                                               else if (surface->mesh.data_lightmapoffsets)
+                                                               const qbyte *lm = surface->lightmapinfo->samples + surface->mesh.data_lightmapoffsets[i];
+                                                               float scale = d_lightstylevalue[surface->lightmapinfo->styles[0]] * (1.0f / 32768.0f);
+                                                               VectorMA(c, scale, lm, c);
+                                                               if (surface->lightmapinfo->styles[1] != 255)
                                                                {
-                                                                       const qbyte *lm = surface->samples + surface->mesh.data_lightmapoffsets[i];
-                                                                       float scale = d_lightstylevalue[surface->styles[0]] * (1.0f / 32768.0f);
+                                                                       int size3 = ((surface->lightmapinfo->extents[0]>>4)+1)*((surface->lightmapinfo->extents[1]>>4)+1)*3;
+                                                                       lm += size3;
+                                                                       scale = d_lightstylevalue[surface->lightmapinfo->styles[1]] * (1.0f / 32768.0f);
                                                                        VectorMA(c, scale, lm, c);
-                                                                       if (surface->styles[1] != 255)
+                                                                       if (surface->lightmapinfo->styles[2] != 255)
                                                                        {
-                                                                               int size3 = ((surface->extents[0]>>4)+1)*((surface->extents[1]>>4)+1)*3;
                                                                                lm += size3;
-                                                                               scale = d_lightstylevalue[surface->styles[1]] * (1.0f / 32768.0f);
+                                                                               scale = d_lightstylevalue[surface->lightmapinfo->styles[2]] * (1.0f / 32768.0f);
                                                                                VectorMA(c, scale, lm, c);
-                                                                               if (surface->styles[2] != 255)
+                                                                               if (surface->lightmapinfo->styles[3] != 255)
                                                                                {
                                                                                        lm += size3;
-                                                                                       scale = d_lightstylevalue[surface->styles[2]] * (1.0f / 32768.0f);
+                                                                                       scale = d_lightstylevalue[surface->lightmapinfo->styles[3]] * (1.0f / 32768.0f);
                                                                                        VectorMA(c, scale, lm, c);
-                                                                                       if (surface->styles[3] != 255)
-                                                                                       {
-                                                                                               lm += size3;
-                                                                                               scale = d_lightstylevalue[surface->styles[3]] * (1.0f / 32768.0f);
-                                                                                               VectorMA(c, scale, lm, c);
-                                                                                       }
                                                                                }
                                                                        }
                                                                }
@@ -816,7 +721,6 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                                                        else
                                                                c[3] = a;
                                                }
-                                               R_Mesh_State(&m);
                                                GL_LockArrays(0, surface->mesh.num_vertices);
                                                R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
                                                GL_LockArrays(0, 0);
@@ -829,14 +733,13 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                                                for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                                {
                                                        surface = texturesurfacelist[texturesurfaceindex];
-                                                       m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
-                                                       m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
-                                                       if (m.tex[1])
-                                                               m.pointer_texcoord[1] = surface->mesh.data_texcoordtexture2f;
+                                                       vertex3f = RSurf_GetVertexPointer(ent, texture, surface, modelorg);
+                                                       R_Mesh_VertexPointer(vertex3f);
+                                                       R_Mesh_TexCoordPointer(0, 2, surface->mesh.data_texcoordtexture2f);
                                                        if (surface->mesh.data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
                                                        {
-                                                               m.pointer_color = varray_color4f;
-                                                               for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
+                                                               R_Mesh_ColorPointer(varray_color4f);
+                                                               for (i = 0, v = vertex3f, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
                                                                {
                                                                        VectorSubtract(v, modelorg, diff);
                                                                        f = 1 - exp(fogdensity/DotProduct(diff, diff));
@@ -848,8 +751,8 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                                                        }
                                                        else
                                                        {
-                                                               m.pointer_color = varray_color4f;
-                                                               for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
+                                                               R_Mesh_ColorPointer(varray_color4f);
+                                                               for (i = 0, v = vertex3f, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
                                                                {
                                                                        VectorSubtract(v, modelorg, diff);
                                                                        f = 1 - exp(fogdensity/DotProduct(diff, diff));
@@ -859,7 +762,6 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                                                                        c[3] = a;
                                                                }
                                                        }
-                                                       R_Mesh_State(&m);
                                                        GL_LockArrays(0, surface->mesh.num_vertices);
                                                        R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
                                                        GL_LockArrays(0, 0);
@@ -870,14 +772,13 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                                                for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                                {
                                                        surface = texturesurfacelist[texturesurfaceindex];
-                                                       m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
-                                                       m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
-                                                       if (m.tex[1])
-                                                               m.pointer_texcoord[1] = surface->mesh.data_texcoordtexture2f;
+                                                       vertex3f = RSurf_GetVertexPointer(ent, texture, surface, modelorg);
+                                                       R_Mesh_VertexPointer(vertex3f);
+                                                       R_Mesh_TexCoordPointer(0, 2, surface->mesh.data_texcoordtexture2f);
                                                        if (surface->mesh.data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
                                                        {
-                                                               m.pointer_color = varray_color4f;
-                                                               for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
+                                                               R_Mesh_ColorPointer(varray_color4f);
+                                                               for (i = 0, v = vertex3f, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
                                                                {
                                                                        c[0] = r;
                                                                        c[1] = g;
@@ -887,10 +788,9 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                                                        }
                                                        else
                                                        {
-                                                               m.pointer_color = NULL;
+                                                               R_Mesh_ColorPointer(NULL);
                                                                GL_Color(r, g, b, a);
                                                        }
-                                                       R_Mesh_State(&m);
                                                        GL_LockArrays(0, surface->mesh.num_vertices);
                                                        R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
                                                        GL_LockArrays(0, 0);
@@ -910,12 +810,12 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                                m.tex[0] = R_GetTexture(texture->skin.base);
                                if (waterscrolling)
                                        m.texmatrix[0] = r_surf_waterscrollmatrix;
+                               R_Mesh_State(&m);
                                for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                {
                                        surface = texturesurfacelist[texturesurfaceindex];
-                                       m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
-                                       m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
-                                       R_Mesh_State(&m);
+                                       R_Mesh_VertexPointer(RSurf_GetVertexPointer(ent, texture, surface, modelorg));
+                                       R_Mesh_TexCoordPointer(0, 2, surface->mesh.data_texcoordtexture2f);
                                        GL_LockArrays(0, surface->mesh.num_vertices);
                                        R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
                                        GL_LockArrays(0, 0);
@@ -927,11 +827,11 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                                dobase = false;
                                GL_Color(0, 0, 0, 1);
                                memset(&m, 0, sizeof(m));
+                               R_Mesh_State(&m);
                                for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                {
                                        surface = texturesurfacelist[texturesurfaceindex];
-                                       m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
-                                       R_Mesh_State(&m);
+                                       R_Mesh_VertexPointer(RSurf_GetVertexPointer(ent, texture, surface, modelorg));
                                        GL_LockArrays(0, surface->mesh.num_vertices);
                                        R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
                                        GL_LockArrays(0, 0);
@@ -949,47 +849,157 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                                if (waterscrolling)
                                        m.texmatrix[1] = r_surf_waterscrollmatrix;
                                m.texrgbscale[1] = 2;
+                               R_Mesh_State(&m);
                                r = ent->colormod[0] * r_lightmapintensity;
                                g = ent->colormod[1] * r_lightmapintensity;
                                b = ent->colormod[2] * r_lightmapintensity;
-                               for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+                               GL_Color(r, g, b, 1);
+                               if (texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
                                {
-                                       surface = texturesurfacelist[texturesurfaceindex];
-                                       memset(&m, 0, sizeof(m));
-                                       m.tex[1] = R_GetTexture(texture->skin.base);
-                                       if (waterscrolling)
-                                               m.texmatrix[1] = r_surf_waterscrollmatrix;
-                                       m.texrgbscale[1] = 2;
-                                       m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
-                                       m.pointer_texcoord[0] = surface->mesh.data_texcoordlightmap2f;
-                                       m.pointer_texcoord[1] = surface->mesh.data_texcoordtexture2f;
-                                       if (surface->lightmaptexture)
+                                       R_Mesh_VertexPointer(varray_vertex3f);
+                                       if (r == 1 && g == 1 && b == 1)
                                        {
-                                               m.tex[0] = R_GetTexture(surface->lightmaptexture);
-                                               m.pointer_color = NULL;
-                                               GL_Color(r, g, b, 1);
+                                               for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+                                               {
+                                                       surface = texturesurfacelist[texturesurfaceindex];
+                                                       RSurf_DeformVertices(ent, texture, surface, modelorg);
+                                                       R_Mesh_TexCoordPointer(0, 2, surface->mesh.data_texcoordlightmap2f);
+                                                       R_Mesh_TexCoordPointer(1, 2, surface->mesh.data_texcoordtexture2f);
+                                                       if (surface->lightmaptexture)
+                                                       {
+                                                               R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
+                                                               R_Mesh_ColorPointer(NULL);
+                                                       }
+                                                       else //if (r == 1 && g == 1 && b == 1)
+                                                       {
+                                                               R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
+                                                               R_Mesh_ColorPointer(surface->mesh.data_lightmapcolor4f);
+                                                       }
+                                                       GL_LockArrays(0, surface->mesh.num_vertices);
+                                                       R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
+                                                       GL_LockArrays(0, 0);
+                                               }
                                        }
-                                       else if (r == 1 && g == 1 && b == 1)
+                                       else
                                        {
-                                               m.tex[0] = R_GetTexture(r_texture_white);
-                                               m.pointer_color = surface->mesh.data_lightmapcolor4f;
+                                               for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+                                               {
+                                                       surface = texturesurfacelist[texturesurfaceindex];
+                                                       RSurf_DeformVertices(ent, texture, surface, modelorg);
+                                                       R_Mesh_TexCoordPointer(0, 2, surface->mesh.data_texcoordlightmap2f);
+                                                       R_Mesh_TexCoordPointer(1, 2, surface->mesh.data_texcoordtexture2f);
+                                                       if (surface->lightmaptexture)
+                                                       {
+                                                               R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
+                                                               R_Mesh_ColorPointer(NULL);
+                                                       }
+                                                       else
+                                                       {
+                                                               R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
+                                                               R_Mesh_ColorPointer(varray_color4f);
+                                                               for (i = 0;i < surface->mesh.num_vertices;i++)
+                                                               {
+                                                                       varray_color4f[i*4+0] = surface->mesh.data_lightmapcolor4f[i*4+0] * r;
+                                                                       varray_color4f[i*4+1] = surface->mesh.data_lightmapcolor4f[i*4+1] * g;
+                                                                       varray_color4f[i*4+2] = surface->mesh.data_lightmapcolor4f[i*4+2] * b;
+                                                                       varray_color4f[i*4+3] = surface->mesh.data_lightmapcolor4f[i*4+3];
+                                                               }
+                                                       }
+                                                       GL_LockArrays(0, surface->mesh.num_vertices);
+                                                       R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
+                                                       GL_LockArrays(0, 0);
+                                               }
+                                       }
+                               }
+                               else
+                               {
+                                       if (r == 1 && g == 1 && b == 1)
+                                       {
+#if 0
+                                               // experimental direct state calls for measuring
+                                               // R_Mesh_ call overhead, do not use!
+                                               R_Mesh_VertexPointer(varray_vertex3f);
+                                               R_Mesh_TexCoordPointer(0, 2, varray_texcoord2f[0]);
+                                               R_Mesh_TexCoordPointer(1, 2, varray_texcoord2f[1]);
+                                               R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
+                                               R_Mesh_ColorPointer(varray_color4f);
+                                               for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+                                               {
+                                                       surface = texturesurfacelist[texturesurfaceindex];
+                                                       qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), surface->mesh.data_vertex3f);
+                                                       qglClientActiveTexture(GL_TEXTURE0_ARB);
+                                                       qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), surface->mesh.data_texcoordlightmap2f);
+                                                       qglClientActiveTexture(GL_TEXTURE1_ARB);
+                                                       qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), surface->mesh.data_texcoordtexture2f);
+                                                       if (surface->lightmaptexture)
+                                                       {
+                                                               R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
+                                                               qglDisableClientState(GL_COLOR_ARRAY);
+                                                               qglColor4f(r, g, b, 1);
+                                                       }
+                                                       else //if (r == 1 && g == 1 && b == 1)
+                                                       {
+                                                               R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
+                                                               qglEnableClientState(GL_COLOR_ARRAY);
+                                                               qglColorPointer(4, GL_FLOAT, sizeof(float[4]), surface->mesh.data_lightmapcolor4f);
+                                                       }
+                                                       qglLockArraysEXT(0, surface->mesh.num_vertices);
+                                                       qglDrawRangeElements(GL_TRIANGLES, 0, surface->mesh.num_vertices, surface->mesh.num_triangles * 3, GL_UNSIGNED_INT, surface->mesh.data_element3i);
+                                                       qglUnlockArraysEXT();
+                                               }
+#else
+                                               for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+                                               {
+                                                       surface = texturesurfacelist[texturesurfaceindex];
+                                                       R_Mesh_VertexPointer(surface->mesh.data_vertex3f);
+                                                       R_Mesh_TexCoordPointer(0, 2, surface->mesh.data_texcoordlightmap2f);
+                                                       R_Mesh_TexCoordPointer(1, 2, surface->mesh.data_texcoordtexture2f);
+                                                       if (surface->lightmaptexture)
+                                                       {
+                                                               R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
+                                                               R_Mesh_ColorPointer(NULL);
+                                                       }
+                                                       else //if (r == 1 && g == 1 && b == 1)
+                                                       {
+                                                               R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
+                                                               R_Mesh_ColorPointer(surface->mesh.data_lightmapcolor4f);
+                                                       }
+                                                       GL_LockArrays(0, surface->mesh.num_vertices);
+                                                       R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
+                                                       GL_LockArrays(0, 0);
+                                               }
+#endif
                                        }
                                        else
                                        {
-                                               m.tex[0] = R_GetTexture(r_texture_white);
-                                               m.pointer_color = varray_color4f;
-                                               for (i = 0;i < surface->mesh.num_vertices;i++)
+                                               for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                                {
-                                                       varray_color4f[i*4+0] = surface->mesh.data_lightmapcolor4f[i*4+0] * r;
-                                                       varray_color4f[i*4+1] = surface->mesh.data_lightmapcolor4f[i*4+1] * g;
-                                                       varray_color4f[i*4+2] = surface->mesh.data_lightmapcolor4f[i*4+2] * b;
-                                                       varray_color4f[i*4+3] = surface->mesh.data_lightmapcolor4f[i*4+3];
+                                                       surface = texturesurfacelist[texturesurfaceindex];
+                                                       R_Mesh_VertexPointer(surface->mesh.data_vertex3f);
+                                                       R_Mesh_TexCoordPointer(0, 2, surface->mesh.data_texcoordlightmap2f);
+                                                       R_Mesh_TexCoordPointer(1, 2, surface->mesh.data_texcoordtexture2f);
+                                                       if (surface->lightmaptexture)
+                                                       {
+                                                               R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
+                                                               R_Mesh_ColorPointer(NULL);
+                                                       }
+                                                       else
+                                                       {
+                                                               R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
+                                                               R_Mesh_ColorPointer(varray_color4f);
+                                                               for (i = 0;i < surface->mesh.num_vertices;i++)
+                                                               {
+                                                                       varray_color4f[i*4+0] = surface->mesh.data_lightmapcolor4f[i*4+0] * r;
+                                                                       varray_color4f[i*4+1] = surface->mesh.data_lightmapcolor4f[i*4+1] * g;
+                                                                       varray_color4f[i*4+2] = surface->mesh.data_lightmapcolor4f[i*4+2] * b;
+                                                                       varray_color4f[i*4+3] = surface->mesh.data_lightmapcolor4f[i*4+3];
+                                                               }
+                                                       }
+                                                       GL_LockArrays(0, surface->mesh.num_vertices);
+                                                       R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
+                                                       GL_LockArrays(0, 0);
                                                }
                                        }
-                                       R_Mesh_State(&m);
-                                       GL_LockArrays(0, surface->mesh.num_vertices);
-                                       R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
-                                       GL_LockArrays(0, 0);
                                }
                        }
                        // single texture
@@ -999,17 +1009,14 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                                GL_DepthMask(true);
                                GL_Color(1, 1, 1, 1);
                                memset(&m, 0, sizeof(m));
+                               R_Mesh_State(&m);
                                for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                {
                                        surface = texturesurfacelist[texturesurfaceindex];
-                                       m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
-                                       m.tex[0] = R_GetTexture(surface->lightmaptexture);
-                                       m.pointer_texcoord[0] = surface->mesh.data_texcoordlightmap2f;
-                                       if (surface->lightmaptexture)
-                                               m.pointer_color = NULL;
-                                       else
-                                               m.pointer_color = surface->mesh.data_lightmapcolor4f;
-                                       R_Mesh_State(&m);
+                                       R_Mesh_VertexPointer(RSurf_GetVertexPointer(ent, texture, surface, modelorg));
+                                       R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
+                                       R_Mesh_TexCoordPointer(0, 2, surface->mesh.data_texcoordlightmap2f);
+                                       R_Mesh_ColorPointer(surface->lightmaptexture ? NULL : surface->mesh.data_lightmapcolor4f);
                                        GL_LockArrays(0, surface->mesh.num_vertices);
                                        R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
                                        GL_LockArrays(0, 0);
@@ -1024,12 +1031,12 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                                m.tex[0] = R_GetTexture(texture->skin.base);
                                if (waterscrolling)
                                        m.texmatrix[0] = r_surf_waterscrollmatrix;
+                               R_Mesh_State(&m);
                                for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                {
                                        surface = texturesurfacelist[texturesurfaceindex];
-                                       m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
-                                       m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
-                                       R_Mesh_State(&m);
+                                       R_Mesh_VertexPointer(RSurf_GetVertexPointer(ent, texture, surface, modelorg));
+                                       R_Mesh_TexCoordPointer(0, 2, surface->mesh.data_texcoordtexture2f);
                                        GL_LockArrays(0, surface->mesh.num_vertices);
                                        R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
                                        GL_LockArrays(0, 0);
@@ -1052,6 +1059,7 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                                m.texrgbscale[0] = 4;
                                colorscale *= 0.25f;
                        }
+                       R_Mesh_State(&m);
                        base = r_ambient.value * (1.0f / 64.0f);
                        r = ent->colormod[0] * colorscale * base;
                        g = ent->colormod[1] * colorscale * base;
@@ -1060,9 +1068,10 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                        for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                        {
                                surface = texturesurfacelist[texturesurfaceindex];
-                               m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
-                               m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
-                               for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
+                               vertex3f = RSurf_GetVertexPointer(ent, texture, surface, modelorg);
+                               R_Mesh_VertexPointer(vertex3f);
+                               R_Mesh_TexCoordPointer(0, 2, surface->mesh.data_texcoordtexture2f);
+                               for (i = 0, v = vertex3f, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
                                {
                                        c[0] = r;
                                        c[1] = g;
@@ -1078,7 +1087,6 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                                        else
                                                c[3] = a;
                                }
-                               R_Mesh_State(&m);
                                GL_LockArrays(0, surface->mesh.num_vertices);
                                R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
                                GL_LockArrays(0, 0);
@@ -1091,12 +1099,12 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                        GL_Color(1, 1, 1, 1);
                        memset(&m, 0, sizeof(m));
                        m.tex[0] = R_GetTexture(texture->skin.detail);
+                       R_Mesh_State(&m);
                        for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                        {
                                surface = texturesurfacelist[texturesurfaceindex];
-                               m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
-                               m.pointer_texcoord[0] = surface->mesh.data_texcoorddetail2f;
-                               R_Mesh_State(&m);
+                               R_Mesh_VertexPointer(RSurf_GetVertexPointer(ent, texture, surface, modelorg));
+                               R_Mesh_TexCoordPointer(0, 2, surface->mesh.data_texcoorddetail2f);
                                GL_LockArrays(0, surface->mesh.num_vertices);
                                R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
                                GL_LockArrays(0, 0);
@@ -1112,6 +1120,7 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                        if (waterscrolling)
                                m.texmatrix[0] = r_surf_waterscrollmatrix;
                        m.pointer_color = varray_color4f;
+                       R_Mesh_State(&m);
                        colorscale = 1;
                        r = ent->colormod[0] * colorscale;
                        g = ent->colormod[1] * colorscale;
@@ -1122,12 +1131,13 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                                for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                {
                                        surface = texturesurfacelist[texturesurfaceindex];
-                                       m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
-                                       m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
+                                       vertex3f = RSurf_GetVertexPointer(ent, texture, surface, modelorg);
+                                       R_Mesh_VertexPointer(vertex3f);
+                                       R_Mesh_TexCoordPointer(0, 2, surface->mesh.data_texcoordtexture2f);
+                                       R_Mesh_ColorPointer(varray_color4f);
                                        if (surface->mesh.data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
                                        {
-                                               m.pointer_color = varray_color4f;
-                                               for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
+                                               for (i = 0, v = vertex3f, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
                                                {
                                                        VectorSubtract(v, modelorg, diff);
                                                        f = 1 - exp(fogdensity/DotProduct(diff, diff));
@@ -1139,8 +1149,7 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                                        }
                                        else
                                        {
-                                               m.pointer_color = varray_color4f;
-                                               for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
+                                               for (i = 0, v = vertex3f, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
                                                {
                                                        VectorSubtract(v, modelorg, diff);
                                                        f = 1 - exp(fogdensity/DotProduct(diff, diff));
@@ -1150,7 +1159,6 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                                                        c[3] = a;
                                                }
                                        }
-                                       R_Mesh_State(&m);
                                        GL_LockArrays(0, surface->mesh.num_vertices);
                                        R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
                                        GL_LockArrays(0, 0);
@@ -1161,12 +1169,13 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                                for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                {
                                        surface = texturesurfacelist[texturesurfaceindex];
-                                       m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
-                                       m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
+                                       vertex3f = RSurf_GetVertexPointer(ent, texture, surface, modelorg);
+                                       R_Mesh_VertexPointer(vertex3f);
+                                       R_Mesh_TexCoordPointer(0, 2, surface->mesh.data_texcoordtexture2f);
                                        if (surface->mesh.data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
                                        {
-                                               m.pointer_color = varray_color4f;
-                                               for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
+                                               R_Mesh_ColorPointer(varray_color4f);
+                                               for (i = 0, v = vertex3f, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
                                                {
                                                        c[0] = r;
                                                        c[1] = g;
@@ -1176,10 +1185,9 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                                        }
                                        else
                                        {
-                                               m.pointer_color = NULL;
+                                               R_Mesh_ColorPointer(NULL);
                                                GL_Color(r, g, b, a);
                                        }
-                                       R_Mesh_State(&m);
                                        GL_LockArrays(0, surface->mesh.num_vertices);
                                        R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
                                        GL_LockArrays(0, 0);
@@ -1208,6 +1216,7 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                        m.tex[0] = R_GetTexture(texture->skin.fog);
                        if (waterscrolling)
                                m.texmatrix[0] = r_surf_waterscrollmatrix;
+                       R_Mesh_State(&m);
                        r = fogcolor[0];
                        g = fogcolor[1];
                        b = fogcolor[2];
@@ -1215,14 +1224,14 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                        for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                        {
                                surface = texturesurfacelist[texturesurfaceindex];
-                               m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
-                               m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
-                               m.pointer_color = varray_color4f;
+                               vertex3f = RSurf_GetVertexPointer(ent, texture, surface, modelorg);
+                               R_Mesh_VertexPointer(vertex3f);
+                               R_Mesh_TexCoordPointer(0, 2, surface->mesh.data_texcoordtexture2f);
+                               R_Mesh_ColorPointer(varray_color4f);
                                //RSurf_FogPassColors_Vertex3f_Color4f(surface->mesh.data_vertex3f, varray_color4f, fogcolor[0], fogcolor[1], fogcolor[2], texture->currentalpha, 1, surface->mesh.num_vertices, modelorg);
                                if (surface->mesh.data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
                                {
-                                       m.pointer_color = varray_color4f;
-                                       for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
+                                       for (i = 0, v = vertex3f, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
                                        {
                                                VectorSubtract(v, modelorg, diff);
                                                f = exp(fogdensity/DotProduct(diff, diff));
@@ -1234,8 +1243,7 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                                }
                                else
                                {
-                                       m.pointer_color = varray_color4f;
-                                       for (i = 0, v = m.pointer_vertex, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
+                                       for (i = 0, v = vertex3f, c = varray_color4f;i < surface->mesh.num_vertices;i++, v += 3, c += 4)
                                        {
                                                VectorSubtract(v, modelorg, diff);
                                                f = exp(fogdensity/DotProduct(diff, diff));
@@ -1245,7 +1253,6 @@ static void R_DrawSurfaceList(const entity_render_t *ent, texture_t *texture, in
                                                c[3] = f * a;
                                        }
                                }
-                               R_Mesh_State(&m);
                                GL_LockArrays(0, surface->mesh.num_vertices);
                                R_Mesh_Draw(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i);
                                GL_LockArrays(0, 0);
@@ -1314,7 +1321,7 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
        Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg);
 
        // update light styles
-       if (!skysurfaces)
+       if (!skysurfaces && model->brushq1.light_styleupdatechains)
        {
                for (i = 0;i < model->brushq1.light_styles;i++)
                {
@@ -1334,11 +1341,42 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
        t = NULL;
        texture = NULL;
        numsurfacelist = 0;
-       for (i = 0, j = model->firstmodelsurface;i < model->nummodelsurfaces;i++, j++)
+       if (ent == r_refdef.worldentity)
+       {
+               for (i = 0, j = model->firstmodelsurface, surface = model->brush.data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
+               {
+                       if (!r_worldsurfacevisible[j])
+                               continue;
+                       if (t != surface->texture)
+                       {
+                               if (numsurfacelist)
+                               {
+                                       R_QueueSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
+                                       numsurfacelist = 0;
+                               }
+                               t = surface->texture;
+                               f = t->currentmaterialflags & flagsmask;
+                               texture = t->currentframe;
+                       }
+                       if (f && surface->mesh.num_triangles)
+                       {
+                               // if lightmap parameters changed, rebuild lightmap texture
+                               if (surface->cached_dlight && surface->lightmapinfo->samples)
+                                       R_BuildLightMap(ent, surface);
+                               // add face to draw list
+                               surfacelist[numsurfacelist++] = surface;
+                               if (numsurfacelist >= maxsurfacelist)
+                               {
+                                       R_QueueSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
+                                       numsurfacelist = 0;
+                               }
+                       }
+               }
+       }
+       else
        {
-               if (ent != r_refdef.worldentity || r_worldsurfacevisible[j])
+               for (i = 0, j = model->firstmodelsurface, surface = model->brush.data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
                {
-                       surface = model->brush.data_surfaces + j;
                        if (t != surface->texture)
                        {
                                if (numsurfacelist)
@@ -1350,10 +1388,10 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
                                f = t->currentmaterialflags & flagsmask;
                                texture = t->currentframe;
                        }
-                       if (f)
+                       if (f && surface->mesh.num_triangles)
                        {
                                // if lightmap parameters changed, rebuild lightmap texture
-                               if (surface->cached_dlight && surface->samples)
+                               if (surface->cached_dlight && surface->lightmapinfo->samples)
                                        R_BuildLightMap(ent, surface);
                                // add face to draw list
                                surfacelist[numsurfacelist++] = surface;
@@ -1444,15 +1482,15 @@ static void R_DrawCollisionSurface(entity_render_t *ent, msurface_t *surface)
 {
        int i;
        rmeshstate_t m;
-       if (!surface->mesh.num_collisiontriangles)
+       if (!surface->num_collisiontriangles)
                return;
        memset(&m, 0, sizeof(m));
-       m.pointer_vertex = surface->mesh.data_collisionvertex3f;
+       m.pointer_vertex = surface->data_collisionvertex3f;
        R_Mesh_State(&m);
        i = (int)(((size_t)surface) / sizeof(msurface_t));
        GL_Color((i & 31) * (1.0f / 32.0f), ((i >> 5) & 31) * (1.0f / 32.0f), ((i >> 10) & 31) * (1.0f / 32.0f), 0.2f);
-       GL_LockArrays(0, surface->mesh.num_collisionvertices);
-       R_Mesh_Draw(surface->mesh.num_collisionvertices, surface->mesh.num_collisiontriangles, surface->mesh.data_collisionelement3i);
+       GL_LockArrays(0, surface->num_collisionvertices);
+       R_Mesh_Draw(surface->num_collisionvertices, surface->num_collisiontriangles, surface->data_collisionelement3i);
        GL_LockArrays(0, 0);
 }
 
@@ -1563,7 +1601,7 @@ void R_Q1BSP_Draw(entity_render_t *ent)
                        if (brush->colbrushf && brush->colbrushf->numtriangles)
                                R_DrawCollisionBrush(brush->colbrushf);
                for (i = 0, surface = model->brush.data_surfaces + model->firstmodelsurface;i < model->nummodelsurfaces;i++, surface++)
-                       if (surface->mesh.num_collisiontriangles)
+                       if (surface->num_collisiontriangles)
                                R_DrawCollisionSurface(ent, surface);
                qglPolygonOffset(0, 0);
        }
@@ -1747,7 +1785,6 @@ void GL_Surf_Init(void)
        Cvar_RegisterVariable(&r_ambient);
        Cvar_RegisterVariable(&r_drawportals);
        Cvar_RegisterVariable(&r_testvis);
-       Cvar_RegisterVariable(&r_floatbuildlightmap);
        Cvar_RegisterVariable(&r_detailtextures);
        Cvar_RegisterVariable(&r_surfaceworldnode);
        Cvar_RegisterVariable(&r_drawcollisionbrushes_polygonfactor);