- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
- GL_DepthFunc(GL_LEQUAL);
-}
-
-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;
- static int newelements[4096*3];
- R_Shadow_RenderLighting_Light_Vertex_Shading(firstvertex, numvertices, diffusecolor2, ambientcolor2);
- for (renders = 0;renders < 4;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.passcolor4f + e[0] * 4) + VectorLength2(rsurface.passcolor4f + e[1] * 4) + VectorLength2(rsurface.passcolor4f + 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, NULL, NULL, 0);
- newnumtriangles = 0;
- newe = newelements;
- stop = false;
- }
- }
- }
- if (newnumtriangles >= 1)
- {
- R_Mesh_Draw(newfirstvertex, newlastvertex - newfirstvertex + 1, 0, newnumtriangles, newelements, NULL, 0, NULL, NULL, 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.passcolor4f + 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 texturenumsurfaces, const msurface_t **texturesurfacelist, const vec3_t lightcolor, float ambientscale, float diffusescale)
-{
- // OpenGL 1.1 path (anything)
- float ambientcolorbase[3], diffusecolorbase[3];
- float ambientcolorpants[3], diffusecolorpants[3];
- float ambientcolorshirt[3], diffusecolorshirt[3];
- const float *surfacecolor = rsurface.texture->dlightcolor;
- const float *surfacepants = rsurface.colormap_pantscolor;
- const float *surfaceshirt = rsurface.colormap_shirtcolor;
- rtexture_t *basetexture = rsurface.texture->basetexture;
- rtexture_t *pantstexture = rsurface.texture->pantstexture;
- rtexture_t *shirttexture = rsurface.texture->shirttexture;
- qboolean dopants = pantstexture && VectorLength2(surfacepants) >= (1.0f / 1048576.0f);
- qboolean doshirt = shirttexture && VectorLength2(surfaceshirt) >= (1.0f / 1048576.0f);
- ambientscale *= 2 * r_refdef.view.colorscale;
- diffusescale *= 2 * r_refdef.view.colorscale;
- ambientcolorbase[0] = lightcolor[0] * ambientscale * surfacecolor[0];ambientcolorbase[1] = lightcolor[1] * ambientscale * surfacecolor[1];ambientcolorbase[2] = lightcolor[2] * ambientscale * surfacecolor[2];
- diffusecolorbase[0] = lightcolor[0] * diffusescale * surfacecolor[0];diffusecolorbase[1] = lightcolor[1] * diffusescale * surfacecolor[1];diffusecolorbase[2] = lightcolor[2] * diffusescale * surfacecolor[2];
- ambientcolorpants[0] = ambientcolorbase[0] * surfacepants[0];ambientcolorpants[1] = ambientcolorbase[1] * surfacepants[1];ambientcolorpants[2] = ambientcolorbase[2] * surfacepants[2];
- diffusecolorpants[0] = diffusecolorbase[0] * surfacepants[0];diffusecolorpants[1] = diffusecolorbase[1] * surfacepants[1];diffusecolorpants[2] = diffusecolorbase[2] * surfacepants[2];
- ambientcolorshirt[0] = ambientcolorbase[0] * surfaceshirt[0];ambientcolorshirt[1] = ambientcolorbase[1] * surfaceshirt[1];ambientcolorshirt[2] = ambientcolorbase[2] * surfaceshirt[2];
- diffusecolorshirt[0] = diffusecolorbase[0] * surfaceshirt[0];diffusecolorshirt[1] = diffusecolorbase[1] * surfaceshirt[1];diffusecolorshirt[2] = diffusecolorbase[2] * surfaceshirt[2];
- RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | (diffusescale > 0 ? BATCHNEED_ARRAY_NORMAL : 0) | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
- rsurface.passcolor4f = (float *)R_FrameData_Alloc((rsurface.batchfirstvertex + rsurface.batchnumvertices) * sizeof(float[4]));
- R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
- R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, 0, 0);
- R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
- R_Mesh_TexBind(0, basetexture);
- R_Mesh_TexMatrix(0, &rsurface.texture->currenttexmatrix);
- R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
- switch(r_shadow_rendermode)
- {
- case R_SHADOW_RENDERMODE_LIGHT_VERTEX3DATTEN:
- R_Mesh_TexBind(1, r_shadow_attenuation3dtexture);
- R_Mesh_TexMatrix(1, &rsurface.entitytoattenuationxyz);
- R_Mesh_TexCombine(1, GL_MODULATE, GL_MODULATE, 1, 1);
- R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
- break;
- case R_SHADOW_RENDERMODE_LIGHT_VERTEX2D1DATTEN:
- R_Mesh_TexBind(2, r_shadow_attenuation2dtexture);
- R_Mesh_TexMatrix(2, &rsurface.entitytoattenuationz);
- R_Mesh_TexCombine(2, GL_MODULATE, GL_MODULATE, 1, 1);
- R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
- // fall through
- case R_SHADOW_RENDERMODE_LIGHT_VERTEX2DATTEN:
- R_Mesh_TexBind(1, r_shadow_attenuation2dtexture);
- R_Mesh_TexMatrix(1, &rsurface.entitytoattenuationxyz);
- R_Mesh_TexCombine(1, GL_MODULATE, GL_MODULATE, 1, 1);
- R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
- break;
- case R_SHADOW_RENDERMODE_LIGHT_VERTEX:
- break;
- default:
- break;
- }
- //R_Mesh_TexBind(0, basetexture);
- R_Shadow_RenderLighting_Light_Vertex_Pass(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.batchelement3i + 3*rsurface.batchfirsttriangle, diffusecolorbase, ambientcolorbase);
- if (dopants)
- {
- R_Mesh_TexBind(0, pantstexture);
- R_Shadow_RenderLighting_Light_Vertex_Pass(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.batchelement3i + 3*rsurface.batchfirsttriangle, diffusecolorpants, ambientcolorpants);
- }
- if (doshirt)
- {
- R_Mesh_TexBind(0, shirttexture);
- R_Shadow_RenderLighting_Light_Vertex_Pass(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.batchelement3i + 3*rsurface.batchfirsttriangle, diffusecolorshirt, ambientcolorshirt);
- }