+ }
+ GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
+ }
+ R_Mesh_State(&m);
+ GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 0);
+ VectorScale(lightcolorbase, colorscale, color2);
+ GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
+ for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
+ {
+ GL_Color(bound(0, color2[0], 1), bound(0, color2[1], 1), bound(0, color2[2], 1), 1);
+ R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, elements);
+ }
+ GL_LockArrays(0, 0);
+}
+
+static void R_Shadow_RenderSurfacesLighting_Light_Dot3(const entity_render_t *ent, const texture_t *texture, int numsurfaces, msurface_t **surfacelist, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float specularscale, qboolean dopants, qboolean doshirt)
+{
+ // ARB path (any Geforce, any Radeon)
+ int surfacelistindex;
+ qboolean doambient = r_shadow_rtlight->ambientscale > 0;
+ qboolean dodiffuse = r_shadow_rtlight->diffusescale > 0;
+ qboolean dospecular = specularscale > 0;
+ if (!doambient && !dodiffuse && !dospecular)
+ return;
+ for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++)
+ {
+ const msurface_t *surface = surfacelist[surfacelistindex];
+ RSurf_SetVertexPointer(ent, texture, surface, r_shadow_entityeyeorigin);
+ 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);
+ }
+ if (doambient)
+ R_Shadow_RenderSurfacesLighting_Light_Dot3_AmbientPass(ent, texture, surface, lightcolorbase, basetexture, r_shadow_rtlight->ambientscale);
+ if (dodiffuse)
+ R_Shadow_RenderSurfacesLighting_Light_Dot3_DiffusePass(ent, texture, surface, lightcolorbase, basetexture, normalmaptexture, r_shadow_rtlight->diffusescale);
+ if (dopants)
+ {
+ if (doambient)
+ R_Shadow_RenderSurfacesLighting_Light_Dot3_AmbientPass(ent, texture, surface, lightcolorpants, pantstexture, r_shadow_rtlight->ambientscale);
+ if (dodiffuse)
+ R_Shadow_RenderSurfacesLighting_Light_Dot3_DiffusePass(ent, texture, surface, lightcolorpants, pantstexture, normalmaptexture, r_shadow_rtlight->diffusescale);
+ }
+ if (doshirt)
+ {
+ if (doambient)
+ R_Shadow_RenderSurfacesLighting_Light_Dot3_AmbientPass(ent, texture, surface, lightcolorshirt, shirttexture, r_shadow_rtlight->ambientscale);
+ if (dodiffuse)
+ R_Shadow_RenderSurfacesLighting_Light_Dot3_DiffusePass(ent, texture, surface, lightcolorshirt, shirttexture, normalmaptexture, r_shadow_rtlight->diffusescale);
+ }
+ if (dospecular)
+ R_Shadow_RenderSurfacesLighting_Light_Dot3_SpecularPass(ent, texture, surface, lightcolorbase, glosstexture, normalmaptexture, specularscale);
+ }
+}
+
+void R_Shadow_RenderSurfacesLighting_Light_Vertex_Pass(const msurface_t *surface, vec3_t diffusecolor2, vec3_t ambientcolor2)
+{
+ int renders;
+ const int *elements = surface->groupmesh->data_element3i + surface->num_firsttriangle * 3;
+ R_Shadow_RenderSurfacesLighting_Light_Vertex_Shading(surface, diffusecolor2, ambientcolor2);
+ for (renders = 0;renders < 64 && (ambientcolor2[0] > renders || ambientcolor2[1] > renders || ambientcolor2[2] > renders || diffusecolor2[0] > renders || diffusecolor2[1] > renders || diffusecolor2[2] > renders);renders++)
+ {
+ int i;
+ float *c;
+#if 1
+ // due to low fillrate on the cards this vertex lighting path is
+ // designed for, we manually cull all triangles that do not
+ // contain a lit vertex
+ int draw;
+ const int *e;
+ int newnumtriangles;
+ int *newe;
+ int newelements[3072];
+ draw = false;
+ newnumtriangles = 0;
+ newe = newelements;
+ for (i = 0, e = elements;i < surface->num_triangles;i++, e += 3)
+ {
+ if (newnumtriangles >= 1024)
+ {
+ GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
+ R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, newnumtriangles, newelements);
+ GL_LockArrays(0, 0);
+ newnumtriangles = 0;
+ newe = newelements;
+ }
+ if (VectorLength2(varray_color4f + e[0] * 4) + VectorLength2(varray_color4f + e[1] * 4) + VectorLength2(varray_color4f + e[2] * 4) >= 0.01)
+ {
+ newe[0] = e[0];
+ newe[1] = e[1];
+ newe[2] = e[2];
+ newnumtriangles++;
+ newe += 3;
+ draw = true;
+ }
+ }
+ if (newnumtriangles >= 1)
+ {
+ GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
+ R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, newnumtriangles, newelements);
+ GL_LockArrays(0, 0);
+ draw = true;
+ }
+ if (!draw)
+ break;
+#else
+ for (i = 0, c = varray_color4f + 4 * surface->num_firstvertex;i < surface->num_vertices;i++, c += 4)
+ if (VectorLength2(c))
+ goto goodpass;
+ break;
+goodpass:
+ GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
+ R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, elements);
+ GL_LockArrays(0, 0);
+#endif
+ // now reduce the intensity for the next overbright pass
+ for (i = 0, c = varray_color4f + 4 * surface->num_firstvertex;i < surface->num_vertices;i++, c += 4)
+ {
+ c[0] = max(0, c[0] - 1);
+ c[1] = max(0, c[1] - 1);
+ c[2] = max(0, c[2] - 1);
+ }
+ }
+}
+
+static void R_Shadow_RenderSurfacesLighting_Light_Vertex(const entity_render_t *ent, const texture_t *texture, int numsurfaces, msurface_t **surfacelist, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float specularscale, qboolean dopants, qboolean doshirt)
+{
+ int surfacelistindex;
+ float ambientcolorbase[3], diffusecolorbase[3];
+ float ambientcolorpants[3], diffusecolorpants[3];
+ float ambientcolorshirt[3], diffusecolorshirt[3];
+ rmeshstate_t m;
+ VectorScale(lightcolorbase, r_shadow_rtlight->ambientscale * 2, ambientcolorbase);
+ VectorScale(lightcolorbase, r_shadow_rtlight->diffusescale * 2, diffusecolorbase);
+ VectorScale(lightcolorpants, r_shadow_rtlight->ambientscale * 2, ambientcolorpants);
+ VectorScale(lightcolorpants, r_shadow_rtlight->diffusescale * 2, diffusecolorpants);
+ VectorScale(lightcolorshirt, r_shadow_rtlight->ambientscale * 2, ambientcolorshirt);
+ VectorScale(lightcolorshirt, r_shadow_rtlight->diffusescale * 2, diffusecolorshirt);
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ memset(&m, 0, sizeof(m));
+ m.tex[0] = R_GetTexture(basetexture);
+ if (r_textureunits.integer >= 2)
+ {
+ // voodoo2
+ m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture);