- m.texmatrix[0] = rsurface.texture->currenttexmatrix;
- if (rsurface.rtlight->currentcubemap != r_texture_whitecube)
- {
- m.texcubemap[1] = R_GetTexture(rsurface.rtlight->currentcubemap);
- m.pointer_texcoord3f[1] = rsurface.vertex3f;
- m.pointer_texcoord_bufferobject[1] = rsurface.vertex3f_bufferobject;
- m.pointer_texcoord_bufferoffset[1] = rsurface.vertex3f_bufferoffset;
- m.texmatrix[1] = rsurface.entitytolight;
- }
- GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
- }
- // this final code is shared
- R_Mesh_TextureState(&m);
- R_Shadow_RenderLighting_Light_Dot3_Finalize(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase[0] * colorscale, lightcolorbase[1] * colorscale, lightcolorbase[2] * colorscale);
-}
-
-static void R_Shadow_RenderLighting_Light_Dot3(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const unsigned short *element3s, int element3i_bufferobject, int element3s_bufferobject, 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 ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt)
-{
- // ARB path (any Geforce, any Radeon)
- qboolean doambient = ambientscale > 0;
- qboolean dodiffuse = diffusescale > 0;
- qboolean dospecular = specularscale > 0;
- if (!doambient && !dodiffuse && !dospecular)
- return;
- R_Mesh_ColorPointer(NULL, 0, 0);
- if (doambient)
- R_Shadow_RenderLighting_Light_Dot3_AmbientPass(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase, basetexture, ambientscale * r_refdef.view.colorscale);
- if (dodiffuse)
- R_Shadow_RenderLighting_Light_Dot3_DiffusePass(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase, basetexture, normalmaptexture, diffusescale * r_refdef.view.colorscale);
- if (dopants)
- {
- if (doambient)
- R_Shadow_RenderLighting_Light_Dot3_AmbientPass(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorpants, pantstexture, ambientscale * r_refdef.view.colorscale);
- if (dodiffuse)
- R_Shadow_RenderLighting_Light_Dot3_DiffusePass(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorpants, pantstexture, normalmaptexture, diffusescale * r_refdef.view.colorscale);
- }
- if (doshirt)
- {
- if (doambient)
- R_Shadow_RenderLighting_Light_Dot3_AmbientPass(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorshirt, shirttexture, ambientscale * r_refdef.view.colorscale);
- if (dodiffuse)
- R_Shadow_RenderLighting_Light_Dot3_DiffusePass(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorshirt, shirttexture, normalmaptexture, diffusescale * r_refdef.view.colorscale);
- }
- if (dospecular)
- R_Shadow_RenderLighting_Light_Dot3_SpecularPass(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase, glosstexture, normalmaptexture, specularscale * r_refdef.view.colorscale);
-}
-
-static void R_Shadow_RenderLighting_Light_Vertex_Pass(int firstvertex, int numvertices, int numtriangles, const int *element3i, vec3_t diffusecolor2, vec3_t ambientcolor2)
-{
- int renders;
- int i;
- int stop;
- int newfirstvertex;
- int newlastvertex;
- int newnumtriangles;
- int *newe;
- const int *e;
- float *c;
- int maxtriangles = 4096;
- int newelements[4096*3];
- R_Shadow_RenderLighting_Light_Vertex_Shading(firstvertex, numvertices, numtriangles, element3i, diffusecolor2, ambientcolor2);
- for (renders = 0;renders < 64;renders++)
- {
- stop = true;
- newfirstvertex = 0;
- newlastvertex = 0;
- newnumtriangles = 0;
- newe = newelements;
- // 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
- // this builds batches of triangles from multiple surfaces and
- // renders them at once
- for (i = 0, e = element3i;i < numtriangles;i++, e += 3)
- {
- if (VectorLength2(rsurface.array_color4f + e[0] * 4) + VectorLength2(rsurface.array_color4f + e[1] * 4) + VectorLength2(rsurface.array_color4f + e[2] * 4) >= 0.01)
- {
- if (newnumtriangles)
- {
- newfirstvertex = min(newfirstvertex, e[0]);
- newlastvertex = max(newlastvertex, e[0]);
- }
- else
- {
- newfirstvertex = e[0];
- newlastvertex = e[0];
- }
- newfirstvertex = min(newfirstvertex, e[1]);
- newlastvertex = max(newlastvertex, e[1]);
- newfirstvertex = min(newfirstvertex, e[2]);
- newlastvertex = max(newlastvertex, e[2]);
- newe[0] = e[0];
- newe[1] = e[1];
- newe[2] = e[2];
- newnumtriangles++;
- newe += 3;
- if (newnumtriangles >= maxtriangles)
- {
- R_Mesh_Draw(newfirstvertex, newlastvertex - newfirstvertex + 1, 0, newnumtriangles, newelements, NULL, 0, 0);
- newnumtriangles = 0;
- newe = newelements;
- stop = false;
- }
- }
- }
- if (newnumtriangles >= 1)
- {
- R_Mesh_Draw(newfirstvertex, newlastvertex - newfirstvertex + 1, 0, newnumtriangles, newelements, NULL, 0, 0);
- stop = false;
- }
- // if we couldn't find any lit triangles, exit early
- if (stop)
- break;
- // now reduce the intensity for the next overbright pass
- // we have to clamp to 0 here incase the drivers have improper
- // handling of negative colors
- // (some old drivers even have improper handling of >1 color)
- stop = true;
- for (i = 0, c = rsurface.array_color4f + 4 * firstvertex;i < numvertices;i++, c += 4)
- {
- if (c[0] > 1 || c[1] > 1 || c[2] > 1)
- {
- c[0] = max(0, c[0] - 1);
- c[1] = max(0, c[1] - 1);
- c[2] = max(0, c[2] - 1);
- stop = false;
- }
- else
- VectorClear(c);
- }
- // another check...
- if (stop)
- break;
- }
-}
-
-static void R_Shadow_RenderLighting_Light_Vertex(int firstvertex, int numvertices, int numtriangles, const int *element3i, 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 ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt)
-{
- // OpenGL 1.1 path (anything)
- float ambientcolorbase[3], diffusecolorbase[3];
- float ambientcolorpants[3], diffusecolorpants[3];
- float ambientcolorshirt[3], diffusecolorshirt[3];
- rmeshstate_t m;
- VectorScale(lightcolorbase, ambientscale * 2 * r_refdef.view.colorscale, ambientcolorbase);
- VectorScale(lightcolorbase, diffusescale * 2 * r_refdef.view.colorscale, diffusecolorbase);
- VectorScale(lightcolorpants, ambientscale * 2 * r_refdef.view.colorscale, ambientcolorpants);
- VectorScale(lightcolorpants, diffusescale * 2 * r_refdef.view.colorscale, diffusecolorpants);
- VectorScale(lightcolorshirt, ambientscale * 2 * r_refdef.view.colorscale, ambientcolorshirt);
- VectorScale(lightcolorshirt, diffusescale * 2 * r_refdef.view.colorscale, diffusecolorshirt);
- memset(&m, 0, sizeof(m));
- m.tex[0] = R_GetTexture(basetexture);
- m.texmatrix[0] = rsurface.texture->currenttexmatrix;
- m.pointer_texcoord[0] = rsurface.texcoordtexture2f;
- m.pointer_texcoord_bufferobject[0] = rsurface.texcoordtexture2f_bufferobject;
- m.pointer_texcoord_bufferoffset[0] = rsurface.texcoordtexture2f_bufferoffset;
- if (r_textureunits.integer >= 2)
- {
- // voodoo2 or TNT
- m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture);
- m.texmatrix[1] = rsurface.entitytoattenuationxyz;
- m.pointer_texcoord3f[1] = rsurface.vertex3f;
- m.pointer_texcoord_bufferobject[1] = rsurface.vertex3f_bufferobject;
- m.pointer_texcoord_bufferoffset[1] = rsurface.vertex3f_bufferoffset;
- if (r_textureunits.integer >= 3)
- {
- // Voodoo4 or Kyro (or Geforce3/Radeon with gl_combine off)
- m.tex[2] = R_GetTexture(r_shadow_attenuation2dtexture);
- m.texmatrix[2] = rsurface.entitytoattenuationz;
- m.pointer_texcoord3f[2] = rsurface.vertex3f;
- m.pointer_texcoord_bufferobject[2] = rsurface.vertex3f_bufferobject;
- m.pointer_texcoord_bufferoffset[2] = rsurface.vertex3f_bufferoffset;
- }