]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_rmain.c
rewrote timing code, now a much better and very different sleeping method, no longer...
[xonotic/darkplaces.git] / gl_rmain.c
index a81e4305a0321105bb368d49d42efb30d88c69cf..4b68e50e6cca6ad9c64c3f297f4170dfab56fe1c 100644 (file)
@@ -132,7 +132,7 @@ rtexture_t *r_texture_notexture;
 rtexture_t *r_texture_whitecube;
 rtexture_t *r_texture_normalizationcube;
 rtexture_t *r_texture_fogattenuation;
-rtexture_t *r_texture_fogintensity;
+//rtexture_t *r_texture_fogintensity;
 
 // information about each possible shader permutation
 r_glsl_permutation_t r_glsl_permutations[SHADERPERMUTATION_COUNT];
@@ -386,7 +386,7 @@ static void R_BuildFogTexture(void)
        double r, alpha;
 #define FOGWIDTH 64
        unsigned char data1[FOGWIDTH][4];
-       unsigned char data2[FOGWIDTH][4];
+       //unsigned char data2[FOGWIDTH][4];
        r = (-1.0/256.0) * (FOGWIDTH * FOGWIDTH);
        for (x = 0;x < FOGWIDTH;x++)
        {
@@ -399,13 +399,13 @@ static void R_BuildFogTexture(void)
                data1[x][1] = 255 - b;
                data1[x][2] = 255 - b;
                data1[x][3] = 255;
-               data2[x][0] = b;
-               data2[x][1] = b;
-               data2[x][2] = b;
-               data2[x][3] = 255;
+               //data2[x][0] = b;
+               //data2[x][1] = b;
+               //data2[x][2] = b;
+               //data2[x][3] = 255;
        }
        r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
-       r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
+       //r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
 }
 
 static const char *builtinshaderstring =
@@ -420,6 +420,9 @@ static const char *builtinshaderstring =
 "varying vec3 CubeVector;\n"
 "varying vec3 LightVector;\n"
 "varying vec3 EyeVector;\n"
+"#ifdef USEFOG\n"
+"varying vec3 EyeVectorModelSpace;\n"
+"#endif\n"
 "\n"
 "varying vec3 VectorS; // direction of S texcoord (sometimes crudely called tangent)\n"
 "varying vec3 VectorT; // direction of T texcoord (sometimes crudely called binormal)\n"
@@ -467,10 +470,13 @@ static const char *builtinshaderstring =
 "#endif\n"
 "\n"
 "      // transform unnormalized eye direction into tangent space\n"
-"      vec3 eyeminusvertex = EyePosition - gl_Vertex.xyz;\n"
-"      EyeVector.x = dot(eyeminusvertex, gl_MultiTexCoord1.xyz);\n"
-"      EyeVector.y = dot(eyeminusvertex, gl_MultiTexCoord2.xyz);\n"
-"      EyeVector.z = dot(eyeminusvertex, gl_MultiTexCoord3.xyz);\n"
+"#ifndef USEFOG\n"
+"      vec3 EyeVectorModelSpace;\n"
+"#endif\n"
+"      EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
+"      EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
+"      EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
+"      EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
 "\n"
 "#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
 "      VectorS = gl_MultiTexCoord1.xyz;\n"
@@ -667,17 +673,19 @@ static const char *builtinshaderstring =
 "      color.rgb *= vec3(texture2D(Texture_Lightmap, TexCoordLightmap)) * DiffuseScale + vec3(AmbientScale);\n"
 "#endif // MODE\n"
 "\n"
+"      color *= gl_Color;\n"
+"\n"
 "#ifdef USEGLOW\n"
 "      color.rgb += vec3(texture2D(Texture_Glow, TexCoord));\n"
 "#endif\n"
 "\n"
 "#ifdef USEFOG\n"
 "      // apply fog\n"
-"      float fog = texture2D(Texture_FogMask, vec2(length(EyeVector)*FogRangeRecip, 0.0)).x;\n"
+"      float fog = texture2D(Texture_FogMask, vec2(length(EyeVectorModelSpace)*FogRangeRecip, 0.0)).x;\n"
 "      color.rgb = color.rgb * fog + FogColor * (1.0 - fog);\n"
 "#endif\n"
 "\n"
-"      gl_FragColor = color * gl_Color;\n"
+"      gl_FragColor = color;\n"
 "}\n"
 "\n"
 "#endif // FRAGMENT_SHADER\n"
@@ -837,7 +845,7 @@ void R_GLSL_Restart_f(void)
        memset(r_glsl_permutations, 0, sizeof(r_glsl_permutations));
 }
 
-void R_SetupSurfaceShader(const entity_render_t *ent, const texture_t *texture, const vec3_t modelorg, const vec3_t lightcolorbase, qboolean modellighting)
+void R_SetupSurfaceShader(const entity_render_t *ent, const texture_t *texture, rtexture_t *lightmaptexture, const vec3_t modelorg, const vec3_t lightcolorbase, qboolean modellighting)
 {
        // select a permutation of the lighting shader appropriate to this
        // combination of texture, entity, light source, and fogging, only use the
@@ -855,17 +863,20 @@ void R_SetupSurfaceShader(const entity_render_t *ent, const texture_t *texture,
        }
        else
        {
-               if (modellighting)
-                       permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTION;
-               else if (r_glsl_deluxemapping.integer >= 1 && r_refdef.worldmodel && r_refdef.worldmodel->brushq3.deluxemapping)
+               if (!(texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
                {
-                       if (r_refdef.worldmodel->brushq3.deluxemapping_modelspace)
-                               permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_MODELSPACE;
-                       else
+                       if (modellighting)
+                               permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTION;
+                       else if (r_glsl_deluxemapping.integer >= 1 && r_refdef.worldmodel && r_refdef.worldmodel->brushq3.deluxemapping && lightmaptexture)
+                       {
+                               if (r_refdef.worldmodel->brushq3.deluxemapping_modelspace)
+                                       permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_MODELSPACE;
+                               else
+                                       permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
+                       }
+                       else if (r_glsl_deluxemapping.integer >= 2) // fake mode
                                permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
                }
-               else if (r_glsl_deluxemapping.integer >= 2) // fake mode
-                       permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
                if (texture->skin.glow)
                        permutation |= SHADERPERMUTATION_GLOW;
        }
@@ -2195,7 +2206,7 @@ void R_Mesh_AddBrushMeshFromPlanes(rmesh_t *mesh, int numplanes, mplane_t *plane
        }
 }
 
-static void R_DrawCollisionBrush(colbrushf_t *brush)
+static void R_DrawCollisionBrush(const colbrushf_t *brush)
 {
        int i;
        R_Mesh_VertexPointer(brush->points->v);
@@ -2206,7 +2217,7 @@ static void R_DrawCollisionBrush(colbrushf_t *brush)
        GL_LockArrays(0, 0);
 }
 
-static void R_DrawCollisionSurface(entity_render_t *ent, msurface_t *surface)
+static void R_DrawCollisionSurface(const entity_render_t *ent, const msurface_t *surface)
 {
        int i;
        if (!surface->num_collisiontriangles)
@@ -2443,25 +2454,24 @@ void RSurf_PrepareVerticesForBatch(const entity_render_t *ent, const texture_t *
        if ((rsurface_entity->frameblend[0].lerp != 1 || rsurface_entity->frameblend[0].frame != 0) && (rsurface_model->surfmesh.data_morphvertex3f || rsurface_model->surfmesh.data_vertexboneweights))
        {
                rsurface_vertex3f = rsurface_array_vertex3f;
+               rsurface_svector3f = NULL;
+               rsurface_tvector3f = NULL;
+               rsurface_normal3f = NULL;
                Mod_Alias_GetMesh_Vertex3f(rsurface_model, rsurface_entity->frameblend, rsurface_array_vertex3f);
-               if (generatetangents || (rsurface_texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2)))
+               if (rsurface_texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
+                       generatetangents = true;
+               if (generatetangents)
+                       generatenormals = true;
+               if (generatenormals && !rsurface_normal3f)
                {
-                       rsurface_svector3f = rsurface_array_svector3f;
-                       rsurface_tvector3f = rsurface_array_tvector3f;
                        rsurface_normal3f = rsurface_array_normal3f;
-                       Mod_BuildTextureVectorsAndNormals(0, rsurface_model->surfmesh.num_vertices, rsurface_model->surfmesh.num_triangles, rsurface_array_vertex3f, rsurface_model->surfmesh.data_texcoordtexture2f, rsurface_model->surfmesh.data_element3i, rsurface_array_svector3f, rsurface_array_tvector3f, rsurface_array_normal3f, r_smoothnormals_areaweighting.integer);
+                       Mod_BuildNormals(0, rsurface_model->surfmesh.num_vertices, rsurface_model->surfmesh.num_triangles, rsurface_array_vertex3f, rsurface_model->surfmesh.data_element3i, rsurface_array_normal3f, r_smoothnormals_areaweighting.integer);
                }
-               else
+               if (generatetangents && !rsurface_svector3f)
                {
-                       rsurface_svector3f = NULL;
-                       rsurface_tvector3f = NULL;
-                       if (generatenormals)
-                       {
-                               rsurface_normal3f = rsurface_array_normal3f;
-                               Mod_BuildNormals(0, rsurface_model->surfmesh.num_vertices, rsurface_model->surfmesh.num_triangles, rsurface_array_vertex3f, rsurface_model->surfmesh.data_element3i, rsurface_array_normal3f, r_smoothnormals_areaweighting.integer);
-                       }
-                       else
-                               rsurface_normal3f = NULL;
+                       Mod_BuildTextureVectorsFromNormals(0, rsurface_model->surfmesh.num_vertices, rsurface_model->surfmesh.num_triangles, rsurface_array_vertex3f, rsurface_model->surfmesh.data_texcoordtexture2f, rsurface_normal3f, rsurface_model->surfmesh.data_element3i, rsurface_array_svector3f, rsurface_array_tvector3f, r_smoothnormals_areaweighting.integer);
+                       rsurface_svector3f = rsurface_array_svector3f;
+                       rsurface_tvector3f = rsurface_array_tvector3f;
                }
        }
        else
@@ -2510,7 +2520,8 @@ void RSurf_PrepareVerticesForBatch(const entity_render_t *ent, const texture_t *
                                for (i = 0;i < 4;i++)
                                        VectorMAMAMAM(1, center, v[i][0], forward, v[i][1], right, v[i][2], up, rsurface_array_vertex3f + (surface->num_firstvertex+i+j) * 3);
                        }
-                       Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_array_vertex3f, rsurface_model->surfmesh.data_texcoordtexture2f, rsurface_model->surfmesh.data_element3i + surface->num_firsttriangle * 3, rsurface_array_svector3f, rsurface_array_tvector3f, rsurface_array_normal3f, r_smoothnormals_areaweighting.integer);
+                       Mod_BuildNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_array_vertex3f, rsurface_model->surfmesh.data_element3i + surface->num_firsttriangle * 3, rsurface_array_normal3f, r_smoothnormals_areaweighting.integer);
+                       Mod_BuildTextureVectorsFromNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_array_vertex3f, rsurface_model->surfmesh.data_texcoordtexture2f, rsurface_array_normal3f, rsurface_model->surfmesh.data_element3i + surface->num_firsttriangle * 3, rsurface_array_svector3f, rsurface_array_tvector3f, r_smoothnormals_areaweighting.integer);
                }
                rsurface_vertex3f = rsurface_array_vertex3f;
                rsurface_svector3f = rsurface_array_svector3f;
@@ -2657,11 +2668,10 @@ static void RSurf_DrawLightmap(const msurface_t *surface, float r, float g, floa
        RSurf_Draw(surface);
 }
 
-static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *texture, int texturenumsurfaces, msurface_t **texturesurfacelist, const vec3_t modelorg)
+static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *texture, rtexture_t *lightmaptexture, int texturenumsurfaces, msurface_t **texturesurfacelist, const vec3_t modelorg)
 {
        int texturesurfaceindex;
        int lightmode;
-       const msurface_t *surface;
        model_t *model = ent->model;
        qboolean applycolor;
        qboolean applyfog;
@@ -2684,9 +2694,9 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                RSurf_PrepareVerticesForBatch(ent, texture, modelorg, false, false, texturenumsurfaces, texturesurfacelist);
                for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                {
+                       const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
                        int k = (int)(((size_t)surface) / sizeof(msurface_t));
                        GL_Color((k & 15) * (1.0f / 16.0f), ((k >> 4) & 15) * (1.0f / 16.0f), ((k >> 8) & 15) * (1.0f / 16.0f), 0.2f);
-                       surface = texturesurfacelist[texturesurfaceindex];
                        RSurf_Draw(surface);
                }
        }
@@ -2730,7 +2740,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                                RSurf_PrepareVerticesForBatch(ent, texture, modelorg, false, false, texturenumsurfaces, texturesurfacelist);
                                for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                {
-                                       surface = texturesurfacelist[texturesurfaceindex];
+                                       const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
                                        RSurf_Draw(surface);
                                }
                                if (skyrendermasked)
@@ -2759,7 +2769,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                R_Mesh_ColorPointer(NULL);
                R_Mesh_ResetTextureState();
                GL_Color(ent->colormod[0], ent->colormod[1], ent->colormod[2], texture->currentalpha);
-               R_SetupSurfaceShader(ent, texture, modelorg, vec3_origin, lightmode == 2);
+               R_SetupSurfaceShader(ent, texture, lightmaptexture, modelorg, vec3_origin, lightmode == 2);
                if (!r_glsl_permutation)
                        return;
                RSurf_PrepareVerticesForBatch(ent, texture, modelorg, true, true, texturenumsurfaces, texturesurfacelist);
@@ -2767,37 +2777,29 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                R_Mesh_TexCoordPointer(1, 3, rsurface_svector3f);
                R_Mesh_TexCoordPointer(2, 3, rsurface_tvector3f);
                R_Mesh_TexCoordPointer(3, 3, rsurface_normal3f);
-               if (lightmode == 2)
+               if (lightmode != 2)
                {
-                       for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+                       R_Mesh_TexCoordPointer(4, 2, model->surfmesh.data_texcoordlightmap2f);
+                       if (lightmaptexture)
                        {
-                               surface = texturesurfacelist[texturesurfaceindex];
-                               RSurf_Draw(surface);
+                               R_Mesh_TexBind(7, R_GetTexture(lightmaptexture));
+                               if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
+                                       R_Mesh_TexBind(8, R_GetTexture(texturesurfacelist[0]->deluxemaptexture));
+                               R_Mesh_ColorPointer(NULL);
                        }
-               }
-               else
-               {
-                       R_Mesh_TexCoordPointer(4, 2, model->surfmesh.data_texcoordlightmap2f);
-                       for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+                       else
                        {
-                               surface = texturesurfacelist[texturesurfaceindex];
-                               if (surface->lightmaptexture)
-                               {
-                                       R_Mesh_TexBind(7, R_GetTexture(surface->lightmaptexture));
-                                       if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
-                                               R_Mesh_TexBind(8, R_GetTexture(surface->deluxemaptexture));
-                                       R_Mesh_ColorPointer(NULL);
-                               }
-                               else
-                               {
-                                       R_Mesh_TexBind(7, R_GetTexture(r_texture_white));
-                                       if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
-                                               R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
-                                       R_Mesh_ColorPointer(model->surfmesh.data_lightmapcolor4f);
-                               }
-                               RSurf_Draw(surface);
+                               R_Mesh_TexBind(7, R_GetTexture(r_texture_white));
+                               if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
+                                       R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
+                               R_Mesh_ColorPointer(model->surfmesh.data_lightmapcolor4f);
                        }
                }
+               for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+               {
+                       const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
+                       RSurf_Draw(surface);
+               }
                qglUseProgramObjectARB(0);
        }
        else if (texture->currentnumlayers)
@@ -2845,26 +2847,27 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                                {
                                        for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                        {
-                                               surface = texturesurfacelist[texturesurfaceindex];
+                                               const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
                                                R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
                                                RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 2, applycolor, applyfog);
                                        }
                                }
+                               else if (lightmaptexture)
+                               {
+                                       R_Mesh_TexBind(0, R_GetTexture(lightmaptexture));
+                                       for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+                                       {
+                                               const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
+                                               RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, applyfog);
+                                       }
+                               }
                                else
                                {
+                                       R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
                                        for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                        {
-                                               surface = texturesurfacelist[texturesurfaceindex];
-                                               if (surface->lightmaptexture)
-                                               {
-                                                       R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
-                                                       RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, applyfog);
-                                               }
-                                               else
-                                               {
-                                                       R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
-                                                       RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 1, applycolor, applyfog);
-                                               }
+                                               const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
+                                               RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 1, applycolor, applyfog);
                                        }
                                }
                                break;
@@ -2879,26 +2882,27 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                                {
                                        for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                        {
-                                               surface = texturesurfacelist[texturesurfaceindex];
+                                               const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
                                                R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
                                                RSurf_DrawLightmap(surface, 1, 1, 1, 1, 2, false, false);
                                        }
                                }
+                               else if (lightmaptexture)
+                               {
+                                       R_Mesh_TexBind(0, R_GetTexture(lightmaptexture));
+                                       for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+                                       {
+                                               const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
+                                               RSurf_DrawLightmap(surface, 1, 1, 1, 1, 0, false, false);
+                                       }
+                               }
                                else
                                {
+                                       R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
                                        for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                        {
-                                               surface = texturesurfacelist[texturesurfaceindex];
-                                               if (surface->lightmaptexture)
-                                               {
-                                                       R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
-                                                       RSurf_DrawLightmap(surface, 1, 1, 1, 1, 0, false, false);
-                                               }
-                                               else
-                                               {
-                                                       R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
-                                                       RSurf_DrawLightmap(surface, 1, 1, 1, 1, 1, false, false);
-                                               }
+                                               const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
+                                               RSurf_DrawLightmap(surface, 1, 1, 1, 1, 1, false, false);
                                        }
                                }
                                GL_LockArrays(0, 0);
@@ -2911,7 +2915,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                                R_Mesh_TextureState(&m);
                                for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                {
-                                       surface = texturesurfacelist[texturesurfaceindex];
+                                       const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
                                        RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, false);
                                }
                                break;
@@ -2926,7 +2930,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                                {
                                        for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                        {
-                                               surface = texturesurfacelist[texturesurfaceindex];
+                                               const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
                                                RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 2, applycolor, applyfog);
                                        }
                                }
@@ -2934,7 +2938,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                                {
                                        for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                        {
-                                               surface = texturesurfacelist[texturesurfaceindex];
+                                               const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
                                                RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 1, applycolor, applyfog);
                                        }
                                }
@@ -2948,7 +2952,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                                R_Mesh_TextureState(&m);
                                for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                {
-                                       surface = texturesurfacelist[texturesurfaceindex];
+                                       const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
                                        RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, applyfog);
                                }
                                break;
@@ -2968,7 +2972,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                                {
                                        int i;
                                        float f, *v, *c;
-                                       surface = texturesurfacelist[texturesurfaceindex];
+                                       const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
                                        for (i = 0, v = (rsurface_vertex3f + 3 * surface->num_firstvertex), c = (rsurface_array_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4)
                                        {
                                                f = VERTEXFOGTABLE(VectorDistance(v, modelorg));
@@ -2995,7 +2999,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                                R_Mesh_ResetTextureState();
                                for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                                {
-                                       surface = texturesurfacelist[texturesurfaceindex];
+                                       const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
                                        for (scale = 1;scale < layertexrgbscale;scale <<= 1)
                                                RSurf_Draw(surface);
                                }
@@ -3021,13 +3025,12 @@ static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, int su
 
        R_Mesh_Matrix(&ent->matrix);
        Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg);
-       R_DrawTextureSurfaceList(ent, texture->currentframe, 1, &surface, modelorg);
+       R_DrawTextureSurfaceList(ent, texture->currentframe, surface->lightmaptexture, 1, &surface, modelorg);
 }
 
-void R_QueueTextureSurfaceList(entity_render_t *ent, texture_t *texture, int texturenumsurfaces, msurface_t **texturesurfacelist, const vec3_t modelorg)
+void R_QueueTextureSurfaceList(entity_render_t *ent, texture_t *texture, rtexture_t *lightmaptexture, int texturenumsurfaces, msurface_t **texturesurfacelist, const vec3_t modelorg)
 {
        int texturesurfaceindex;
-       const msurface_t *surface;
        vec3_t tempcenter, center;
        if (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT)
        {
@@ -3036,7 +3039,7 @@ void R_QueueTextureSurfaceList(entity_render_t *ent, texture_t *texture, int tex
                {
                        for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
                        {
-                               surface = texturesurfacelist[texturesurfaceindex];
+                               const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
                                tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f;
                                tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f;
                                tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f;
@@ -3046,7 +3049,7 @@ void R_QueueTextureSurfaceList(entity_render_t *ent, texture_t *texture, int tex
                }
        }
        else
-               R_DrawTextureSurfaceList(ent, texture, texturenumsurfaces, texturesurfacelist, modelorg);
+               R_DrawTextureSurfaceList(ent, texture, lightmaptexture, texturenumsurfaces, texturesurfacelist, modelorg);
 }
 
 extern void R_BuildLightMap(const entity_render_t *ent, msurface_t *surface);
@@ -3054,8 +3057,8 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
 {
        int i, j, f, flagsmask;
        int counttriangles = 0;
-       msurface_t *surface, **surfacechain;
        texture_t *t, *texture;
+       rtexture_t *lmap;
        model_t *model = ent->model;
        vec3_t modelorg;
        const int maxsurfacelist = 1024;
@@ -3069,6 +3072,7 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
        // update light styles
        if (!skysurfaces && model->brushq1.light_styleupdatechains)
        {
+               msurface_t *surface, **surfacechain;
                for (i = 0;i < model->brushq1.light_styles;i++)
                {
                        if (model->brushq1.light_stylevalue[i] != r_refdef.lightstylevalue[model->brushq1.light_style[i]])
@@ -3085,22 +3089,25 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
        flagsmask = skysurfaces ? MATERIALFLAG_SKY : (MATERIALFLAG_WATER | MATERIALFLAG_WALL);
        f = 0;
        t = NULL;
+       lmap = NULL;
        texture = NULL;
        numsurfacelist = 0;
        if (ent == r_refdef.worldentity)
        {
+               msurface_t *surface;
                for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
                {
                        if (!r_worldsurfacevisible[j])
                                continue;
-                       if (t != surface->texture)
+                       if (t != surface->texture || lmap != surface->lightmaptexture)
                        {
                                if (numsurfacelist)
                                {
-                                       R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
+                                       R_QueueTextureSurfaceList(ent, texture, lmap, numsurfacelist, surfacelist, modelorg);
                                        numsurfacelist = 0;
                                }
                                t = surface->texture;
+                               lmap = surface->lightmaptexture;
                                texture = t->currentframe;
                                f = texture->currentmaterialflags & flagsmask;
                        }
@@ -3114,7 +3121,7 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
                                counttriangles += surface->num_triangles;
                                if (numsurfacelist >= maxsurfacelist)
                                {
-                                       R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
+                                       R_QueueTextureSurfaceList(ent, texture, lmap, numsurfacelist, surfacelist, modelorg);
                                        numsurfacelist = 0;
                                }
                        }
@@ -3122,16 +3129,18 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
        }
        else
        {
+               msurface_t *surface;
                for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
                {
-                       if (t != surface->texture)
+                       if (t != surface->texture || lmap != surface->lightmaptexture)
                        {
                                if (numsurfacelist)
                                {
-                                       R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
+                                       R_QueueTextureSurfaceList(ent, texture, lmap, numsurfacelist, surfacelist, modelorg);
                                        numsurfacelist = 0;
                                }
                                t = surface->texture;
+                               lmap = surface->lightmaptexture;
                                texture = t->currentframe;
                                f = texture->currentmaterialflags & flagsmask;
                        }
@@ -3145,14 +3154,14 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
                                counttriangles += surface->num_triangles;
                                if (numsurfacelist >= maxsurfacelist)
                                {
-                                       R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
+                                       R_QueueTextureSurfaceList(ent, texture, lmap, numsurfacelist, surfacelist, modelorg);
                                        numsurfacelist = 0;
                                }
                        }
                }
        }
        if (numsurfacelist)
-               R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
+               R_QueueTextureSurfaceList(ent, texture, lmap, numsurfacelist, surfacelist, modelorg);
        renderstats.entities_triangles += counttriangles;
        if (gl_support_fragment_shader)
                qglUseProgramObjectARB(0);
@@ -3160,7 +3169,7 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
        if (r_showcollisionbrushes.integer && model->brush.num_brushes && !skysurfaces)
        {
                int i;
-               msurface_t *surface;
+               const msurface_t *surface;
                q3mbrush_t *brush;
                R_Mesh_Matrix(&ent->matrix);
                R_Mesh_ColorPointer(NULL);
@@ -3181,6 +3190,7 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
        if (r_showtris.integer || r_shownormals.integer)
        {
                int k, l;
+               msurface_t *surface;
                const int *elements;
                vec3_t v;
                GL_DepthTest(true);