+ if (dobase && dolightmap && gl_combine.integer)
+ {
+ dobase = false;
+ 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_color = varray_color4f;
+ 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);
+ 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;
+ if (surface->lightmaptexture)
+ {
+ m.tex[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)
+ {
+ VectorSubtract(v, modelorg, diff);
+ f = 1 - exp(fogdensity/DotProduct(diff, diff));
+ c[0] = f * r;
+ c[1] = f * g;
+ c[2] = f * b;
+ c[3] = a;
+ }
+ }
+ else
+ {
+ m.pointer_color = NULL;
+ GL_Color(r, g, b, a);
+ }
+ }
+ else
+ {
+ m.tex[0] = R_GetTexture(r_texture_white);
+ m.pointer_color = varray_color4f;
+#ifdef LHREMOVESOON
+ if (surface->styles[0] != 255 || surface->dlightframe == r_framecount)
+#else
+ if (surface->styles[0] != 255)
+#endif
+ {
+ 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;
+ 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);
+ }
+ }
+ }
+ }
+ }
+#ifdef LHREMOVESOON
+ if (surface->dlightframe == r_framecount)
+ {
+ int l;
+ float worldvertex[3];
+ // TODO: make this work with autosprite which uses identitymatrix
+ Matrix4x4_Transform(&ent->matrix, v, worldvertex);
+ for (l = 0;l < r_numdlights;l++)
+ {
+ if (surface->dlightbits[l >> 5] & (1 << (l & 31)))
+ {
+ float f2;
+ dlight_t *light = &r_dlight[l];
+ f2 = VectorDistance2(worldvertex, light->origin) + LIGHTOFFSET;
+ if (f2 < light->rtlight.lightmap_cullradius2)
+ {
+ f2 = (1.0f / f2) - light->rtlight.lightmap_subtract;
+ VectorMA(c, f2, light->rtlight.lightmap_light, c);
+ }
+ }
+ }
+ }
+#endif
+ c[0] *= r;
+ c[1] *= g;
+ c[2] *= b;
+ if (fogallpasses)
+ {
+ 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_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);
+ }
+ }
+ if (dobase)
+ {
+ dobase = false;
+ memset(&m, 0, sizeof(m));
+ m.tex[0] = R_GetTexture(texture->skin.base);
+ if (waterscrolling)
+ m.texmatrix[0] = r_surf_waterscrollmatrix;
+ m.texmatrix[0] = r_surf_waterscrollmatrix;
+ m.pointer_color = varray_color4f;
+ colorscale = 1;
+ if (gl_combine.integer)
+ {
+ m.texrgbscale[0] = 4;
+ colorscale *= 0.25f;
+ }
+ r = ent->colormod[0] * colorscale;
+ g = ent->colormod[1] * colorscale;
+ b = ent->colormod[2] * colorscale;
+ a = texture->currentalpha;
+ if (dolightmap)
+ {
+ 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)
+ {
+ 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);
+ }
+ }
+ }
+ }
+ }
+#ifdef LHREMOVESOON
+ if (surface->dlightframe == r_framecount)
+ {
+ // TODO: make this work with autosprite which uses identitymatrix
+ Matrix4x4_Transform(&ent->matrix, v, worldvertex);
+ for (l = 0;l < r_numdlights;l++)
+ {
+ if (surface->dlightbits[l >> 5] & (1 << (l & 31)))
+ {
+ float f2;
+ dlight_t *light = &r_dlight[l];
+ f2 = VectorDistance2(worldvertex, light->origin) + LIGHTOFFSET;
+ if (f2 < light->rtlight.lightmap_cullradius2)
+ {
+ f2 = (1.0f / f2) - light->rtlight.lightmap_subtract;
+ VectorMA(c, f2, light->rtlight.lightmap_light, c);
+ }
+ }
+ }
+ }
+#endif
+ c[0] *= r;
+ c[1] *= g;
+ c[2] *= b;
+ if (fogallpasses)
+ {
+ 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;
+ }
+ 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);
+ }
+ }
+ else
+ {
+ if (fogallpasses)
+ {
+ 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;
+ 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)
+ {
+ VectorSubtract(v, modelorg, diff);
+ f = 1 - exp(fogdensity/DotProduct(diff, diff));
+ c[0] = r * f;
+ c[1] = g * f;
+ c[2] = b * f;
+ c[3] = surface->mesh.data_lightmapcolor4f[i*4+3] * a;
+ }
+ }
+ 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)
+ {
+ VectorSubtract(v, modelorg, diff);
+ f = 1 - exp(fogdensity/DotProduct(diff, diff));
+ c[0] = r * f;
+ c[1] = g * f;
+ c[2] = b * f;
+ 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);
+ }
+ }
+ else
+ {
+ 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;
+ 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)
+ {
+ c[0] = r;
+ c[1] = g;
+ c[2] = b;
+ c[3] = surface->mesh.data_lightmapcolor4f[i*4+3] * a;
+ }
+ }
+ else
+ {
+ m.pointer_color = 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);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if (!dolightmap && dobase)
+ {
+ dolightmap = false;
+ dobase = false;
+ GL_Color(ent->colormod[0], ent->colormod[1], ent->colormod[2], 1);
+ memset(&m, 0, sizeof(m));
+ m.tex[0] = R_GetTexture(texture->skin.base);
+ if (waterscrolling)
+ m.texmatrix[0] = r_surf_waterscrollmatrix;
+ 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);
+ 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);
+ }
+ }
+ if (r_lightmapintensity <= 0 && dolightmap && dobase)
+ {
+ dolightmap = false;
+ dobase = false;
+ GL_Color(0, 0, 0, 1);
+ memset(&m, 0, sizeof(m));
+ for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+ {
+ surface = texturesurfacelist[texturesurfaceindex];
+ m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
+ 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);
+ }
+ }
+ if (r_textureunits.integer >= 2 && gl_combine.integer && dolightmap && dobase)
+ {
+ // dualtexture combine
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_DepthMask(true);
+ dolightmap = false;
+ dobase = false;
+ 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;
+ r = ent->colormod[0] * r_lightmapintensity;
+ g = ent->colormod[1] * r_lightmapintensity;
+ b = ent->colormod[2] * r_lightmapintensity;
+ for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+ {
+ 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)
+ {
+ m.tex[0] = R_GetTexture(surface->lightmaptexture);
+ m.pointer_color = NULL;
+ GL_Color(r, g, b, 1);
+ }
+ else if (r == 1 && g == 1 && b == 1)
+ {
+ m.tex[0] = R_GetTexture(r_texture_white);
+ m.pointer_color = surface->mesh.data_lightmapcolor4f;
+ }
+ else
+ {
+ m.tex[0] = R_GetTexture(r_texture_white);
+ m.pointer_color = 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];
+ }
+ }
+ 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
+ if (dolightmap)
+ {
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_DepthMask(true);
+ GL_Color(1, 1, 1, 1);
+ memset(&m, 0, sizeof(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);
+ 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);
+ }
+ }
+ if (dobase)
+ {
+ GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
+ GL_DepthMask(false);
+ GL_Color(r_lightmapintensity * ent->colormod[0], r_lightmapintensity * ent->colormod[1], r_lightmapintensity * ent->colormod[2], 1);
+ memset(&m, 0, sizeof(m));
+ m.tex[0] = R_GetTexture(texture->skin.base);
+ if (waterscrolling)
+ m.texmatrix[0] = r_surf_waterscrollmatrix;
+ 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);
+ 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);
+ }
+ }
+ }
+ if (doambient)
+ {
+ doambient = false;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ GL_DepthMask(false);
+ memset(&m, 0, sizeof(m));
+ m.tex[0] = R_GetTexture(texture->skin.base);
+ if (waterscrolling)
+ m.texmatrix[0] = r_surf_waterscrollmatrix;
+ m.pointer_color = varray_color4f;
+ colorscale = 1;
+ if (gl_combine.integer)
+ {
+ m.texrgbscale[0] = 4;
+ colorscale *= 0.25f;
+ }
+ base = r_ambient.value * (1.0f / 64.0f);
+ r = ent->colormod[0] * colorscale * base;
+ g = ent->colormod[1] * colorscale * base;
+ b = ent->colormod[2] * colorscale * base;
+ a = texture->currentalpha;
+ 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)
+ {
+ c[0] = r;
+ c[1] = g;
+ c[2] = b;
+ if (fogallpasses)
+ {
+ 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;
+ }
+ 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);
+ }
+ }
+ // marklights based vertex dlight rendering... evil and broken
+#if 0
+ GL_BlendFunc(GL_ONE, GL_ONE);
+ GL_DepthMask(false);
+ memset(&m, 0, sizeof(m));
+ m.tex[0] = R_GetTexture(texture->skin.base);
+ if (waterscrolling)
+ m.texmatrix[0] = r_surf_waterscrollmatrix;
+ m.pointer_color = varray_color4f;
+ r = ent->colormod[0] * r_lightmapintensity;
+ g = ent->colormod[1] * r_lightmapintensity;
+ b = ent->colormod[2] * r_lightmapintensity;
+ for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+ {
+ qboolean lit;
+ surface = texturesurfacelist[texturesurfaceindex];
+ if (surface->dlightframe != r_framecount)
+ continue;
+ m.pointer_vertex = RSurf_GetVertexPointer(ent, surface);
+ m.pointer_texcoord[0] = surface->mesh.data_texcoordtexture2f;
+ lit = false;
+ 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] = 1;
+ // TODO: make this work with autosprite which uses identitymatrix or change autosprite
+ Matrix4x4_Transform(&ent->matrix, v, worldvertex);
+ for (l = 0;l < r_numdlights;l++)
+ {
+ if (surface->dlightbits[l >> 5] & (1 << (l & 31)))
+ {
+ float f2;
+ dlight_t *light = &r_dlight[l];
+ f2 = VectorDistance2(worldvertex, light->origin) + LIGHTOFFSET;
+ if (f2 < light->rtlight.lightmap_cullradius2)
+ {
+ f2 = (1.0f / f2) - light->rtlight.lightmap_subtract;
+ VectorMA(c, f2, light->rtlight.lightmap_light, c);
+ lit = true;
+ }
+ }
+ }
+ c[0] *= r;
+ c[1] *= g;
+ c[2] *= b;
+ if (fogallpasses)
+ {
+ 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;
+ }
+ if (!lit)
+ continue;
+ 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);
+ }
+#endif
+ if (dodetail)
+ {
+ GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
+ GL_DepthMask(false);
+ GL_Color(1, 1, 1, 1);
+ memset(&m, 0, sizeof(m));
+ m.tex[0] = R_GetTexture(texture->skin.detail);
+ 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);
+ 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);
+ }
+ }
+ if (doglow)
+ {
+ // if glow was not already done using multitexture, do it now.
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ GL_DepthMask(false);
+ memset(&m, 0, sizeof(m));
+ m.tex[0] = R_GetTexture(texture->skin.glow);
+ if (waterscrolling)
+ m.texmatrix[0] = r_surf_waterscrollmatrix;
+ m.pointer_color = varray_color4f;
+ colorscale = 1;
+ r = ent->colormod[0] * colorscale;
+ g = ent->colormod[1] * colorscale;
+ b = ent->colormod[2] * colorscale;
+ a = texture->currentalpha;
+ if (fogallpasses)
+ {
+ 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 (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)
+ {
+ VectorSubtract(v, modelorg, diff);
+ f = 1 - exp(fogdensity/DotProduct(diff, diff));
+ c[0] = f * r;
+ c[1] = f * g;
+ c[2] = f * b;
+ c[3] = surface->mesh.data_lightmapcolor4f[i*4+3] * a;
+ }
+ }
+ 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)
+ {
+ VectorSubtract(v, modelorg, diff);
+ f = 1 - exp(fogdensity/DotProduct(diff, diff));
+ c[0] = f * r;
+ c[1] = f * g;
+ c[2] = f * b;
+ 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);
+ }
+ }
+ else
+ {
+ 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 (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)
+ {
+ c[0] = r;
+ c[1] = g;
+ c[2] = b;
+ c[3] = surface->mesh.data_lightmapcolor4f[i*4+3] * a;
+ }
+ }
+ else
+ {
+ m.pointer_color = 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);
+ }
+ }
+ }
+ if (dofogpass)
+ {
+ // if this is opaque use alpha blend which will darken the earlier
+ // passes cheaply.
+ //
+ // if this is an alpha blended material, all the earlier passes
+ // were darkened by fog already, so we only need to add the fog
+ // color ontop through the fog mask texture
+ //
+ // if this is an additive blended material, all the earlier passes
+ // 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).
+ if (!fogallpasses)
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ else
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GL_DepthMask(false);
+ memset(&m, 0, sizeof(m));
+ m.tex[0] = R_GetTexture(texture->skin.fog);
+ if (waterscrolling)
+ m.texmatrix[0] = r_surf_waterscrollmatrix;
+ r = fogcolor[0];
+ g = fogcolor[1];
+ b = fogcolor[2];
+ a = texture->currentalpha;
+ 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;
+ //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)
+ {
+ VectorSubtract(v, modelorg, diff);
+ f = exp(fogdensity/DotProduct(diff, diff));
+ c[0] = r;
+ c[1] = g;
+ c[2] = b;
+ c[3] = surface->mesh.data_lightmapcolor4f[i*4+3] * f * a;
+ }
+ }
+ 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)
+ {
+ VectorSubtract(v, modelorg, diff);
+ f = exp(fogdensity/DotProduct(diff, diff));
+ c[0] = r;
+ c[1] = g;
+ c[2] = b;
+ 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);
+ }
+ }
+ }
+ if (texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
+ qglEnable(GL_CULL_FACE);
+}
+
+static void RSurfShader_Transparent_Callback(const void *calldata1, int calldata2)
+{
+ const entity_render_t *ent = calldata1;
+ const msurface_t *surface = ent->model->brush.data_surfaces + calldata2;
+ vec3_t modelorg;
+ texture_t *texture;
+#ifdef LHREMOVESOON
+ rmeshstate_t m;
+ float base, colorscale;
+ float args[4] = {0.05f,0,0,0.04f};
+ matrix4x4_t scrollmatrix;
+#endif
+
+ texture = surface->texture;
+ if (texture->basematerialflags & MATERIALFLAG_SKY)
+ return; // transparent sky is too difficult
+ R_UpdateTextureInfo(ent, texture);
+
+ R_Mesh_Matrix(&ent->matrix);
+ Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg);
+ R_DrawSurfaceList(ent, texture, 1, &surface, modelorg);
+#ifdef LHREMOVESOON
+ GL_DepthTest(!(texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
+ GL_DepthMask(!(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT));
+ if (texture->currentmaterialflags & MATERIALFLAG_ADD)
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ else if (texture->currentmaterialflags & MATERIALFLAG_ALPHA)
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);