]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_rmain.c
fix incredibly stupid bug in Memory_Init, it was clearing the pool chain AFTER alloca...
[xonotic/darkplaces.git] / gl_rmain.c
index 45ee836993b3910cafa12f8c8920633fc35746b5..4303a2ace0951bc33f50777e232f8da6326e3734 100644 (file)
@@ -28,8 +28,6 @@ int r_framecount;
 
 mplane_t frustum[5];
 
-matrix4x4_t r_identitymatrix;
-
 renderstats_t renderstats;
 
 // true during envmap command capture
@@ -450,7 +448,6 @@ void gl_main_newmap(void)
 
 void GL_Main_Init(void)
 {
-       Matrix4x4_CreateIdentity(&r_identitymatrix);
 // FIXME: move this to client?
        FOG_registercvars();
        Cvar_RegisterVariable(&r_showtris);
@@ -862,7 +859,7 @@ static void R_BlendView(void)
        GL_SetupView_Mode_Ortho(0, 0, 1, 1, -10, 100);
        GL_DepthMask(true);
        GL_DepthTest(false);
-       R_Mesh_Matrix(&r_identitymatrix);
+       R_Mesh_Matrix(&identitymatrix);
        // vertex coordinates for a quad that covers the screen exactly
        varray_vertex3f[0] = 0;varray_vertex3f[1] = 0;varray_vertex3f[2] = 0;
        varray_vertex3f[3] = 1;varray_vertex3f[4] = 0;varray_vertex3f[5] = 0;
@@ -1091,7 +1088,8 @@ void R_RenderView(void)
        R_ClearScreen();
        R_Textures_Frame();
        R_UpdateFog();
-       R_TimeReport("setup");
+       if (r_timereport_active)
+               R_TimeReport("setup");
 
        qglDepthFunc(GL_LEQUAL);
        qglPolygonOffset(0, 0);
@@ -1103,7 +1101,8 @@ void R_RenderView(void)
        qglDisable(GL_POLYGON_OFFSET_FILL);
 
        R_BlendView();
-       R_TimeReport("blendview");
+       if (r_timereport_active)
+               R_TimeReport("blendview");
 
        GL_Scissor(0, 0, vid.width, vid.height);
        GL_ScissorTest(false);
@@ -1137,7 +1136,8 @@ void CSQC_R_ClearScreen (void)
        R_ClearScreen();
        R_Textures_Frame();
        R_UpdateFog();
-       R_TimeReport("setup");
+       if (r_timereport_active)
+               R_TimeReport("setup");
 }
 
 //[515]: csqc
@@ -1153,7 +1153,8 @@ void CSQC_R_RenderScene (void)
        qglDisable(GL_POLYGON_OFFSET_FILL);
 
        R_BlendView();
-       R_TimeReport("blendview");
+       if (r_timereport_active)
+               R_TimeReport("blendview");
 
        GL_Scissor(0, 0, vid.width, vid.height);
        GL_ScissorTest(false);
@@ -1186,10 +1187,12 @@ void R_RenderScene(void)
        R_SkyStartFrame();
 
        R_WorldVisibility();
-       R_TimeReport("worldvis");
+       if (r_timereport_active)
+               R_TimeReport("worldvis");
 
        R_MarkEntities();
-       R_TimeReport("markentity");
+       if (r_timereport_active)
+               R_TimeReport("markentity");
 
        R_Shadow_UpdateWorldLightSelection();
 
@@ -1216,21 +1219,25 @@ void R_RenderScene(void)
                        if (r_refdef.extraupdate)
                                S_ExtraUpdate ();
 
-                       GL_ShowTrisColor(0.025, 0.025, 0, 1);
+                       if (r_showtrispass)
+                               GL_ShowTrisColor(0.025, 0.025, 0, 1);
                        if (r_refdef.worldmodel && r_refdef.worldmodel->DrawSky)
                        {
                                r_refdef.worldmodel->DrawSky(r_refdef.worldentity);
-                               R_TimeReport("worldsky");
+                               if (r_timereport_active)
+                                       R_TimeReport("worldsky");
                        }
 
-                       if (R_DrawBrushModelsSky())
+                       if (R_DrawBrushModelsSky() && r_timereport_active)
                                R_TimeReport("bmodelsky");
 
-                       GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
+                       if (r_showtrispass)
+                               GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
                        if (r_refdef.worldmodel && r_refdef.worldmodel->Draw)
                        {
                                r_refdef.worldmodel->Draw(r_refdef.worldentity);
-                               R_TimeReport("world");
+                               if (r_timereport_active)
+                                       R_TimeReport("world");
                        }
                }
 
@@ -1238,49 +1245,60 @@ void R_RenderScene(void)
                if (r_refdef.extraupdate)
                        S_ExtraUpdate ();
 
-               GL_ShowTrisColor(0, 0.015, 0, 1);
+               if (r_showtrispass)
+                       GL_ShowTrisColor(0, 0.015, 0, 1);
 
                R_DrawModels();
-               R_TimeReport("models");
+               if (r_timereport_active)
+                       R_TimeReport("models");
 
                // don't let sound skip if going slow
                if (r_refdef.extraupdate)
                        S_ExtraUpdate ();
 
-               GL_ShowTrisColor(0, 0, 0.033, 1);
+               if (r_showtrispass)
+                       GL_ShowTrisColor(0, 0, 0.033, 1);
                R_ShadowVolumeLighting(false);
-               R_TimeReport("rtlights");
+               if (r_timereport_active)
+                       R_TimeReport("rtlights");
 
                // don't let sound skip if going slow
                if (r_refdef.extraupdate)
                        S_ExtraUpdate ();
 
-               GL_ShowTrisColor(0.1, 0, 0, 1);
+               if (r_showtrispass)
+                       GL_ShowTrisColor(0.1, 0, 0, 1);
 
                if (cl.csqc_vidvars.drawworld)
                {
                        R_DrawLightningBeams();
-                       R_TimeReport("lightning");
+                       if (r_timereport_active)
+                               R_TimeReport("lightning");
 
                        R_DrawParticles();
-                       R_TimeReport("particles");
+                       if (r_timereport_active)
+                               R_TimeReport("particles");
 
                        R_DrawExplosions();
-                       R_TimeReport("explosions");
+                       if (r_timereport_active)
+                               R_TimeReport("explosions");
                }
 
                R_MeshQueue_RenderTransparent();
-               R_TimeReport("drawtrans");
+               if (r_timereport_active)
+                       R_TimeReport("drawtrans");
 
                if (cl.csqc_vidvars.drawworld)
                {
                        R_DrawCoronas();
-                       R_TimeReport("coronas");
+                       if (r_timereport_active)
+                               R_TimeReport("coronas");
                }
                if(cl.csqc_vidvars.drawcrosshair)
                {
                        R_DrawWorldCrosshair();
-                       R_TimeReport("crosshair");
+                       if (r_timereport_active)
+                               R_TimeReport("crosshair");
                }
 
                VM_AddPolygonsToMeshQueue();
@@ -1312,7 +1330,7 @@ void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, floa
        GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        GL_DepthMask(false);
        GL_DepthTest(true);
-       R_Mesh_Matrix(&r_identitymatrix);
+       R_Mesh_Matrix(&identitymatrix);
 
        vertex3f[ 0] = mins[0];vertex3f[ 1] = mins[1];vertex3f[ 2] = mins[2];
        vertex3f[ 3] = maxs[0];vertex3f[ 4] = mins[1];vertex3f[ 5] = mins[2];
@@ -1477,7 +1495,7 @@ void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, rtexture_
                fog = VERTEXFOGTABLE(VectorDistance(origin, r_vieworigin));
        ifog = 1 - fog;
 
-       R_Mesh_Matrix(&r_identitymatrix);
+       R_Mesh_Matrix(&identitymatrix);
        GL_BlendFunc(blendfunc1, blendfunc2);
        GL_DepthMask(false);
        GL_DepthTest(!depthdisable);
@@ -1579,7 +1597,7 @@ void R_Mesh_AddBrushMeshFromPlanes(rmesh_t *mesh, int numplanes, mplane_t *plane
        }
 }
 
-void R_Texture_AddLayer(texture_t *t, qboolean depthmask, int blendfunc1, int blendfunc2, texturelayertype_t type, rtexture_t *texture, matrix4x4_t *matrix, float r, float g, float b, float a)
+static void R_Texture_AddLayer(texture_t *t, qboolean depthmask, int blendfunc1, int blendfunc2, texturelayertype_t type, rtexture_t *texture, const matrix4x4_t *matrix, float r, float g, float b, float a)
 {
        texturelayer_t *layer;
        layer = t->currentlayers + t->currentnumlayers++;
@@ -1635,17 +1653,17 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
        if (t->currentmaterialflags & MATERIALFLAG_WATER && r_waterscroll.value != 0)
                t->currenttexmatrix = r_waterscrollmatrix;
        else
-               t->currenttexmatrix = r_identitymatrix;
+               t->currenttexmatrix = identitymatrix;
        t->currentnumlayers = 0;
        if (!(t->currentmaterialflags & MATERIALFLAG_NODRAW))
        {
                if (gl_lightmaps.integer)
-                       R_Texture_AddLayer(t, true, GL_ONE, GL_ZERO, TEXTURELAYERTYPE_LITTEXTURE_MULTIPASS, r_texture_white, &r_identitymatrix, 1, 1, 1, 1);
+                       R_Texture_AddLayer(t, true, GL_ONE, GL_ZERO, TEXTURELAYERTYPE_LITTEXTURE_MULTIPASS, r_texture_white, &identitymatrix, 1, 1, 1, 1);
                else if (t->currentmaterialflags & MATERIALFLAG_SKY)
                {
                        // transparent sky would be ridiculous
                        if (!(t->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
-                               R_Texture_AddLayer(t, true, GL_ONE, GL_ZERO, TEXTURELAYERTYPE_SKY, r_texture_white, &r_identitymatrix, fogcolor[0], fogcolor[1], fogcolor[2], 1);
+                               R_Texture_AddLayer(t, true, GL_ONE, GL_ZERO, TEXTURELAYERTYPE_SKY, r_texture_white, &identitymatrix, fogcolor[0], fogcolor[1], fogcolor[2], 1);
                }
                else
                {
@@ -1730,7 +1748,7 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
                                        // were darkened by fog already, and we should not add fog color
                                        // (because the background was not darkened, there is no fog color
                                        // that was lost behind it).
-                                       R_Texture_AddLayer(t, false, GL_SRC_ALPHA, (t->currentmaterialflags & MATERIALFLAG_TRANSPARENT) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, TEXTURELAYERTYPE_FOG, t->skin.fog, &r_identitymatrix, fogcolor[0], fogcolor[1], fogcolor[2], t->currentalpha);
+                                       R_Texture_AddLayer(t, false, GL_SRC_ALPHA, (t->currentmaterialflags & MATERIALFLAG_TRANSPARENT) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, TEXTURELAYERTYPE_FOG, t->skin.fog, &identitymatrix, fogcolor[0], fogcolor[1], fogcolor[2], t->currentalpha);
                                }
                        }
                }
@@ -1751,72 +1769,44 @@ float *rsurface_tvector3f;
 float *rsurface_normal3f;
 float *rsurface_lightmapcolor4f;
 
-void RSurf_SetVertexPointer(const entity_render_t *ent, const texture_t *texture, const msurface_t *surface, const vec3_t modelorg)
+void RSurf_SetVertexPointer(const entity_render_t *ent, const texture_t *texture, const msurface_t *surface, const vec3_t modelorg, qboolean generatenormals, qboolean generatetangents)
 {
-       int i, j;
-       float center[3], forward[3], right[3], up[3], v[4][3];
-       matrix4x4_t matrix1, imatrix1;
        if ((ent->frameblend[0].lerp != 1 || ent->frameblend[0].frame != 0) && (surface->groupmesh->data_morphvertex3f || surface->groupmesh->data_vertexboneweights))
        {
                rsurface_vertex3f = varray_vertex3f;
-               rsurface_svector3f = NULL;
-               rsurface_tvector3f = NULL;
-               rsurface_normal3f = NULL;
                Mod_Alias_GetMesh_Vertex3f(ent->model, ent->frameblend, surface->groupmesh, rsurface_vertex3f);
-       }
-       else
-       {
-               rsurface_vertex3f = surface->groupmesh->data_vertex3f;
-               rsurface_svector3f = surface->groupmesh->data_svector3f;
-               rsurface_tvector3f = surface->groupmesh->data_tvector3f;
-               rsurface_normal3f = surface->groupmesh->data_normal3f;
-       }
-       if (texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE2)
-       {
-               if (!rsurface_svector3f)
+               if (generatetangents || (texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2)))
                {
                        rsurface_svector3f = varray_svector3f;
                        rsurface_tvector3f = varray_tvector3f;
                        rsurface_normal3f = varray_normal3f;
                        Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_vertex3f, surface->groupmesh->data_texcoordtexture2f, surface->groupmesh->data_element3i + surface->num_firsttriangle * 3, rsurface_svector3f, rsurface_tvector3f, rsurface_normal3f, r_smoothnormals_areaweighting.integer);
                }
-               // a single autosprite surface can contain multiple sprites...
-               VectorClear(forward);
-               VectorClear(right);
-               VectorSet(up, 0, 0, 1);
-               for (j = 0;j < surface->num_vertices - 3;j += 4)
+               else
                {
-                       VectorClear(center);
-                       for (i = 0;i < 4;i++)
-                               VectorAdd(center, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (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, (rsurface_normal3f + 3 * surface->num_firstvertex) + j*3, (rsurface_svector3f + 3 * surface->num_firstvertex) + j*3, (rsurface_tvector3f + 3 * surface->num_firstvertex) + j*3, center);
-                       Matrix4x4_Invert_Simple(&imatrix1, &matrix1);
-                       for (i = 0;i < 4;i++)
-                               Matrix4x4_Transform(&imatrix1, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i)*3, v[i]);
-                       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 + (surface->num_firstvertex+i+j) * 3);
+                       rsurface_svector3f = NULL;
+                       rsurface_tvector3f = NULL;
+                       if (generatenormals)
+                       {
+                               rsurface_normal3f = varray_normal3f;
+                               Mod_BuildNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_vertex3f, surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle, rsurface_normal3f, r_smoothnormals_areaweighting.integer);
+                       }
+                       else
+                               rsurface_normal3f = NULL;
                }
-               rsurface_vertex3f = varray_vertex3f;
-               rsurface_svector3f = NULL;
-               rsurface_tvector3f = NULL;
-               rsurface_normal3f = NULL;
        }
-       else if (texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE)
+       else
        {
-               if (!rsurface_svector3f)
-               {
-                       rsurface_svector3f = varray_svector3f;
-                       rsurface_tvector3f = varray_tvector3f;
-                       rsurface_normal3f = varray_normal3f;
-                       Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_vertex3f, surface->groupmesh->data_texcoordtexture2f, surface->groupmesh->data_element3i + surface->num_firsttriangle * 3, rsurface_svector3f, rsurface_tvector3f, rsurface_normal3f, r_smoothnormals_areaweighting.integer);
-               }
+               rsurface_vertex3f = surface->groupmesh->data_vertex3f;
+               rsurface_svector3f = surface->groupmesh->data_svector3f;
+               rsurface_tvector3f = surface->groupmesh->data_tvector3f;
+               rsurface_normal3f = surface->groupmesh->data_normal3f;
+       }
+       if (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;
                Matrix4x4_Transform(&ent->inversematrix, r_viewforward, forward);
                Matrix4x4_Transform(&ent->inversematrix, r_viewright, right);
                Matrix4x4_Transform(&ent->inversematrix, r_viewup, up);
@@ -1832,22 +1822,35 @@ void RSurf_SetVertexPointer(const entity_render_t *ent, const texture_t *texture
                        Matrix4x4_Invert_Simple(&imatrix1, &matrix1);
                        for (i = 0;i < 4;i++)
                                Matrix4x4_Transform(&imatrix1, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i)*3, v[i]);
+                       if (texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE2)
+                       {
+                               forward[0] = modelorg[0] - center[0];
+                               forward[1] = modelorg[1] - center[1];
+                               forward[2] = 0;
+                               VectorNormalize(forward);
+                               right[0] = forward[1];
+                               right[1] = -forward[0];
+                               right[2] = 0;
+                               VectorSet(up, 0, 0, 1);
+                       }
                        for (i = 0;i < 4;i++)
                                VectorMAMAMAM(1, center, v[i][0], forward, v[i][1], right, v[i][2], up, varray_vertex3f + (surface->num_firstvertex+i+j) * 3);
                }
                rsurface_vertex3f = varray_vertex3f;
-               rsurface_svector3f = NULL;
-               rsurface_tvector3f = NULL;
-               rsurface_normal3f = NULL;
+               rsurface_svector3f = varray_svector3f;
+               rsurface_tvector3f = varray_tvector3f;
+               rsurface_normal3f = varray_normal3f;
+               Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_vertex3f, surface->groupmesh->data_texcoordtexture2f, surface->groupmesh->data_element3i + surface->num_firsttriangle * 3, rsurface_svector3f, rsurface_tvector3f, rsurface_normal3f, r_smoothnormals_areaweighting.integer);
        }
        R_Mesh_VertexPointer(rsurface_vertex3f);
 }
 
-void RSurf_SetColorPointer(const entity_render_t *ent, const msurface_t *surface, const vec3_t modelorg, float r, float g, float b, float a, int lightmode, qboolean applycolor, qboolean applyfog)
+static void RSurf_DrawLightmap(const entity_render_t *ent, const texture_t *texture, const msurface_t *surface, const vec3_t modelorg, float r, float g, float b, float a, int lightmode, qboolean applycolor, qboolean applyfog)
 {
        int i;
        float f;
        float *v, *c, *c2;
+       RSurf_SetVertexPointer(ent, texture, surface, modelorg, lightmode == 2, false);
        if (lightmode >= 2)
        {
                // model lighting
@@ -1857,11 +1860,6 @@ void RSurf_SetColorPointer(const entity_render_t *ent, const msurface_t *surface
                if (R_LightModel(ambientcolor4f, diffusecolor, diffusenormal, ent, r*0.5f, g*0.5f, b*0.5f, a, false))
                {
                        rsurface_lightmapcolor4f = varray_color4f;
-                       if (rsurface_normal3f == NULL)
-                       {
-                               rsurface_normal3f = varray_normal3f;
-                               Mod_BuildNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_vertex3f, surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle, rsurface_normal3f, r_smoothnormals_areaweighting.integer);
-                       }
                        R_LightModel_CalcVertexColors(ambientcolor4f, diffusecolor, diffusenormal, surface->groupmesh->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, rsurface_normal3f + 3 * surface->num_firstvertex, rsurface_lightmapcolor4f + 4 * surface->num_firstvertex);
                        r = 1;
                        g = 1;
@@ -1880,13 +1878,13 @@ void RSurf_SetColorPointer(const entity_render_t *ent, const msurface_t *surface
        }
        else if (lightmode >= 1)
        {
-               if (surface->lightmapinfo)
+               if (surface->lightmapinfo && surface->lightmapinfo->stainsamples)
                {
                        for (i = 0, c = varray_color4f + 4 * surface->num_firstvertex;i < surface->num_vertices;i++, c += 4)
                        {
-                               const unsigned char *lm = surface->lightmapinfo->samples + (surface->groupmesh->data_lightmapoffsets + surface->num_firstvertex)[i];
-                               if (lm)
+                               if (surface->lightmapinfo->samples)
                                {
+                                       const unsigned char *lm = surface->lightmapinfo->samples + (surface->groupmesh->data_lightmapoffsets + surface->num_firstvertex)[i];
                                        float scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[0]] * (1.0f / 32768.0f);
                                        VectorScale(lm, scale, c);
                                        if (surface->lightmapinfo->styles[1] != 255)
@@ -1958,6 +1956,16 @@ void RSurf_SetColorPointer(const entity_render_t *ent, const msurface_t *surface
        }
        R_Mesh_ColorPointer(rsurface_lightmapcolor4f);
        GL_Color(r, g, b, a);
+       GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
+       R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
+       GL_LockArrays(0, 0);
+}
+
+static void RSurf_Draw(const msurface_t *surface)
+{
+       GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
+       R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
+       GL_LockArrays(0, 0);
 }
 
 static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *texture, int texturenumsurfaces, const msurface_t **texturesurfacelist, const vec3_t modelorg)
@@ -1966,6 +1974,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
        int lightmode;
        const msurface_t *surface;
        qboolean applycolor;
+       qboolean applyfog;
        rmeshstate_t m;
        if (texture->currentmaterialflags & MATERIALFLAG_NODRAW)
                return;
@@ -2003,6 +2012,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                        layercolor[3] = layer->color[3];
                        GL_Color(layercolor[0], layercolor[1], layercolor[2], layercolor[3]);
                        applycolor = layercolor[0] != 1 || layercolor[1] != 1 || layercolor[2] != 1 || layercolor[3] != 1;
+                       applyfog = (layer->flags & TEXTURELAYERFLAG_FOGDARKEN) != 0;
                        switch (layer->type)
                        {
                        case TEXTURELAYERTYPE_SKY:
@@ -2038,10 +2048,8 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                                        for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                        {
                                                surface = texturesurfacelist[texturesurfaceindex];
-                                               RSurf_SetVertexPointer(ent, texture, surface, modelorg);
-                                               GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
-                                               R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
-                                               GL_LockArrays(0, 0);
+                                               RSurf_SetVertexPointer(ent, texture, surface, modelorg, false, false);
+                                               RSurf_Draw(surface);
                                        }
                                        if (skyrendermasked)
                                                GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
@@ -2054,30 +2062,35 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                                m.texrgbscale[1] = layertexrgbscale;
                                m.pointer_color = varray_color4f;
                                R_Mesh_State(&m);
-                               for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+                               if (lightmode == 2)
                                {
-                                       surface = texturesurfacelist[texturesurfaceindex];
-                                       RSurf_SetVertexPointer(ent, texture, surface, modelorg);
-                                       R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f);
-                                       R_Mesh_TexCoordPointer(1, 2, surface->groupmesh->data_texcoordtexture2f);
-                                       if (lightmode == 2)
+                                       for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                        {
+                                               surface = texturesurfacelist[texturesurfaceindex];
+                                               R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f);
+                                               R_Mesh_TexCoordPointer(1, 2, surface->groupmesh->data_texcoordtexture2f);
                                                R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
-                                               RSurf_SetColorPointer(ent, surface, modelorg, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 2, applycolor, layer->flags & TEXTURELAYERFLAG_FOGDARKEN);
-                                       }
-                                       else if (surface->lightmaptexture)
-                                       {
-                                               R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
-                                               RSurf_SetColorPointer(ent, surface, modelorg, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, layer->flags & TEXTURELAYERFLAG_FOGDARKEN);
+                                               RSurf_DrawLightmap(ent, texture, surface, modelorg, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 2, applycolor, applyfog);
                                        }
-                                       else
+                               }
+                               else
+                               {
+                                       for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                        {
-                                               R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
-                                               RSurf_SetColorPointer(ent, surface, modelorg, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 1, applycolor, layer->flags & TEXTURELAYERFLAG_FOGDARKEN);
+                                               surface = texturesurfacelist[texturesurfaceindex];
+                                               R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f);
+                                               R_Mesh_TexCoordPointer(1, 2, surface->groupmesh->data_texcoordtexture2f);
+                                               if (surface->lightmaptexture)
+                                               {
+                                                       R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
+                                                       RSurf_DrawLightmap(ent, texture, surface, modelorg, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, applyfog);
+                                               }
+                                               else
+                                               {
+                                                       R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
+                                                       RSurf_DrawLightmap(ent, texture, surface, modelorg, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 1, applycolor, applyfog);
+                                               }
                                        }
-                                       GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
-                                       R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
-                                       GL_LockArrays(0, 0);
                                }
                                break;
                        case TEXTURELAYERTYPE_LITTEXTURE_MULTIPASS:
@@ -2087,29 +2100,33 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                                m.pointer_color = varray_color4f;
                                m.texrgbscale[0] = layertexrgbscale;
                                R_Mesh_State(&m);
-                               for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+                               if (lightmode == 2)
                                {
-                                       surface = texturesurfacelist[texturesurfaceindex];
-                                       RSurf_SetVertexPointer(ent, texture, surface, modelorg);
-                                       R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f);
-                                       if (lightmode == 2)
+                                       for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                        {
+                                               surface = texturesurfacelist[texturesurfaceindex];
+                                               R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f);
                                                R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
-                                               RSurf_SetColorPointer(ent, surface, modelorg, 1, 1, 1, 1, 2, false, false);
-                                       }
-                                       else if (surface->lightmaptexture)
-                                       {
-                                               R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
-                                               R_Mesh_ColorPointer(NULL);
+                                               RSurf_DrawLightmap(ent, texture, surface, modelorg, 1, 1, 1, 1, 2, false, false);
                                        }
-                                       else
+                               }
+                               else
+                               {
+                                       for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                        {
-                                               R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
-                                               RSurf_SetColorPointer(ent, surface, modelorg, 1, 1, 1, 1, 1, false, false);
+                                               surface = texturesurfacelist[texturesurfaceindex];
+                                               R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f);
+                                               if (surface->lightmaptexture)
+                                               {
+                                                       R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
+                                                       RSurf_DrawLightmap(ent, texture, surface, modelorg, 1, 1, 1, 1, 0, false, false);
+                                               }
+                                               else
+                                               {
+                                                       R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
+                                                       RSurf_DrawLightmap(ent, texture, surface, modelorg, 1, 1, 1, 1, 1, false, false);
+                                               }
                                        }
-                                       GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
-                                       R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
-                                       GL_LockArrays(0, 0);
                                }
                                GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
                                memset(&m, 0, sizeof(m));
@@ -2121,12 +2138,8 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                                for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                {
                                        surface = texturesurfacelist[texturesurfaceindex];
-                                       RSurf_SetVertexPointer(ent, texture, surface, modelorg);
                                        R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
-                                       RSurf_SetColorPointer(ent, surface, modelorg, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, layer->flags & TEXTURELAYERFLAG_FOGDARKEN);
-                                       GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
-                                       R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
-                                       GL_LockArrays(0, 0);
+                                       RSurf_DrawLightmap(ent, texture, surface, modelorg, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, applyfog);
                                }
                                break;
                        case TEXTURELAYERTYPE_LITTEXTURE_VERTEX:
@@ -2136,15 +2149,23 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                                m.texrgbscale[0] = layertexrgbscale;
                                m.pointer_color = varray_color4f;
                                R_Mesh_State(&m);
-                               for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+                               if (lightmode == 2)
                                {
-                                       surface = texturesurfacelist[texturesurfaceindex];
-                                       RSurf_SetVertexPointer(ent, texture, surface, modelorg);
-                                       R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
-                                       RSurf_SetColorPointer(ent, surface, modelorg, layercolor[0], layercolor[1], layercolor[2], layercolor[3], lightmode ? lightmode : 1, applycolor, layer->flags & TEXTURELAYERFLAG_FOGDARKEN);
-                                       GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
-                                       R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
-                                       GL_LockArrays(0, 0);
+                                       for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+                                       {
+                                               surface = texturesurfacelist[texturesurfaceindex];
+                                               R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
+                                               RSurf_DrawLightmap(ent, texture, surface, modelorg, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 2, applycolor, applyfog);
+                                       }
+                               }
+                               else
+                               {
+                                       for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+                                       {
+                                               surface = texturesurfacelist[texturesurfaceindex];
+                                               R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
+                                               RSurf_DrawLightmap(ent, texture, surface, modelorg, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 1, applycolor, applyfog);
+                                       }
                                }
                                break;
                        case TEXTURELAYERTYPE_TEXTURE:
@@ -2157,12 +2178,8 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                                for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                {
                                        surface = texturesurfacelist[texturesurfaceindex];
-                                       RSurf_SetVertexPointer(ent, texture, surface, modelorg);
                                        R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
-                                       RSurf_SetColorPointer(ent, surface, modelorg, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, layer->flags & TEXTURELAYERFLAG_FOGDARKEN);
-                                       GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
-                                       R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
-                                       GL_LockArrays(0, 0);
+                                       RSurf_DrawLightmap(ent, texture, surface, modelorg, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, applyfog);
                                }
                                break;
                        case TEXTURELAYERTYPE_FOG:
@@ -2178,7 +2195,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                                        int i;
                                        float f, *v, *c;
                                        surface = texturesurfacelist[texturesurfaceindex];
-                                       RSurf_SetVertexPointer(ent, texture, surface, modelorg);
+                                       RSurf_SetVertexPointer(ent, texture, surface, modelorg, false, false);
                                        if (layer->texture)
                                                R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
                                        R_Mesh_ColorPointer(varray_color4f);
@@ -2190,9 +2207,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                                                c[2] = layercolor[2];
                                                c[3] = f * layercolor[3];
                                        }
-                                       GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
-                                       R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
-                                       GL_LockArrays(0, 0);
+                                       RSurf_Draw(surface);
                                }
                                break;
                        default:
@@ -2210,11 +2225,9 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                                for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                {
                                        surface = texturesurfacelist[texturesurfaceindex];
-                                       RSurf_SetVertexPointer(ent, texture, surface, modelorg);
-                                       GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
+                                       RSurf_SetVertexPointer(ent, texture, surface, modelorg, false, false);
                                        for (scale = 1;scale < layertexrgbscale;scale <<= 1)
-                                               R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
-                                       GL_LockArrays(0, 0);
+                                               RSurf_Draw(surface);
                                }
                        }
                }
@@ -2230,14 +2243,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                        for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                        {
                                surface = texturesurfacelist[texturesurfaceindex];
-                               RSurf_SetVertexPointer(ent, texture, surface, modelorg);
-                               if (!rsurface_svector3f)
-                               {
-                                       rsurface_svector3f = varray_svector3f;
-                                       rsurface_tvector3f = varray_tvector3f;
-                                       rsurface_normal3f = varray_normal3f;
-                                       Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_vertex3f, surface->groupmesh->data_texcoordtexture2f, surface->groupmesh->data_element3i + surface->num_firsttriangle * 3, rsurface_svector3f, rsurface_tvector3f, rsurface_normal3f, r_smoothnormals_areaweighting.integer);
-                               }
+                               RSurf_SetVertexPointer(ent, texture, surface, modelorg, false, true);
                                GL_Color(1, 0, 0, 1);
                                qglBegin(GL_LINES);
                                for (j = 0, k = surface->num_firstvertex;j < surface->num_vertices;j++, k++)
@@ -2370,7 +2376,7 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
                        if (f && surface->num_triangles)
                        {
                                // if lightmap parameters changed, rebuild lightmap texture
-                               if (surface->cached_dlight && surface->lightmapinfo->samples)
+                               if (surface->cached_dlight)
                                        R_BuildLightMap(ent, surface);
                                // add face to draw list
                                surfacelist[numsurfacelist++] = surface;
@@ -2401,7 +2407,7 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
                        if (f && surface->num_triangles)
                        {
                                // if lightmap parameters changed, rebuild lightmap texture
-                               if (surface->cached_dlight && surface->lightmapinfo->samples)
+                               if (surface->cached_dlight)
                                        R_BuildLightMap(ent, surface);
                                // add face to draw list
                                surfacelist[numsurfacelist++] = surface;