static int numcubemaps;
static cubemapinfo_t cubemaps[MAX_CUBEMAPS];
-#define SHADERPERMUTATION_SPECULAR (1<<0)
-#define SHADERPERMUTATION_FOG (1<<1)
-#define SHADERPERMUTATION_CUBEFILTER (1<<2)
-#define SHADERPERMUTATION_OFFSETMAPPING (1<<3)
-#define SHADERPERMUTATION_SURFACENORMALIZE (1<<4)
-#define SHADERPERMUTATION_GEFORCEFX (1<<5)
-#define SHADERPERMUTATION_COUNT (1<<6)
+#define SHADERPERMUTATION_COLORMAPPING (1<<0)
+#define SHADERPERMUTATION_SPECULAR (1<<1)
+#define SHADERPERMUTATION_FOG (1<<2)
+#define SHADERPERMUTATION_CUBEFILTER (1<<3)
+#define SHADERPERMUTATION_OFFSETMAPPING (1<<4)
+#define SHADERPERMUTATION_SURFACENORMALIZE (1<<5)
+#define SHADERPERMUTATION_GEFORCEFX (1<<6)
+#define SHADERPERMUTATION_COUNT (1<<7)
GLhandleARB r_shadow_program_light[SHADERPERMUTATION_COUNT];
"uniform myhalf SpecularScale;\n"
"#endif\n"
"\n"
+"#ifdef USECOLORMAPPING\n"
+"uniform myhvec3 Color_Pants;\n"
+"uniform myhvec3 Color_Shirt;\n"
+"#endif\n"
+"\n"
"uniform sampler2D Texture_Normal;\n"
"uniform sampler2D Texture_Color;\n"
+"uniform sampler2D Texture_Pants;\n"
+"uniform sampler2D Texture_Shirt;\n"
"#ifdef USESPECULAR\n"
"uniform sampler2D Texture_Gloss;\n"
"#endif\n"
"\n"
" // calculate shading\n"
" myhvec3 diffusenormal = myhvec3(normalize(LightVector));\n"
-" myhvec3 color = myhvec3(texture2D(Texture_Color, TexCoord)) * (AmbientScale + DiffuseScale * max(dot(surfacenormal, diffusenormal), 0.0));\n"
+" myhvec4 texturecolor = myhvec4(texture2D(Texture_Color, TexCoord));\n"
+" colorscale *= texturecolor.a;\n"
+" myhvec3 color = myhvec3(texturecolor);\n"
+"#ifdef USECOLORMAPPING\n"
+" color += myhvec3(texture2D(Texture_Pants, TexCoord)) * Color_Pants + myhvec3(texture2D(Texture_Shirt, TexCoord)) * Color_Shirt;\n"
+"#endif\n"
+" color *= (AmbientScale + DiffuseScale * max(dot(surfacenormal, diffusenormal), 0.0));\n"
"#ifdef USESPECULAR\n"
" myhvec3 specularnormal = myhvec3(normalize(diffusenormal + myhvec3(normalize(EyeVector))));\n"
" color += myhvec3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);\n"
fragstring = (char *)FS_LoadFile("glsl/light.frag", tempmempool, false, NULL);
for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
{
+ char permutationname[256];
vertstrings_count = 0;
fragstrings_count = 0;
+ permutationname[0] = 0;
+ if (i & SHADERPERMUTATION_COLORMAPPING)
+ {
+ vertstrings_list[vertstrings_count++] = "#define USECOLORMAPPING\n";
+ fragstrings_list[fragstrings_count++] = "#define USECOLORMAPPING\n";
+ strlcat(permutationname, " colormapping", sizeof(permutationname));
+ }
if (i & SHADERPERMUTATION_SPECULAR)
{
vertstrings_list[vertstrings_count++] = "#define USESPECULAR\n";
fragstrings_list[fragstrings_count++] = "#define USESPECULAR\n";
+ strlcat(permutationname, " specular", sizeof(permutationname));
}
if (i & SHADERPERMUTATION_FOG)
{
vertstrings_list[vertstrings_count++] = "#define USEFOG\n";
fragstrings_list[fragstrings_count++] = "#define USEFOG\n";
+ strlcat(permutationname, " fog", sizeof(permutationname));
}
if (i & SHADERPERMUTATION_CUBEFILTER)
{
vertstrings_list[vertstrings_count++] = "#define USECUBEFILTER\n";
fragstrings_list[fragstrings_count++] = "#define USECUBEFILTER\n";
+ strlcat(permutationname, " cubefilter", sizeof(permutationname));
}
if (i & SHADERPERMUTATION_OFFSETMAPPING)
{
vertstrings_list[vertstrings_count++] = "#define USEOFFSETMAPPING\n";
fragstrings_list[fragstrings_count++] = "#define USEOFFSETMAPPING\n";
+ strlcat(permutationname, " offsetmapping", sizeof(permutationname));
}
if (i & SHADERPERMUTATION_SURFACENORMALIZE)
{
vertstrings_list[vertstrings_count++] = "#define SURFACENORMALIZE\n";
fragstrings_list[fragstrings_count++] = "#define SURFACENORMALIZE\n";
+ strlcat(permutationname, " surfacenormalize", sizeof(permutationname));
}
if (i & SHADERPERMUTATION_GEFORCEFX)
{
continue;
vertstrings_list[vertstrings_count++] = "#define GEFORCEFX\n";
fragstrings_list[fragstrings_count++] = "#define GEFORCEFX\n";
+ strlcat(permutationname, " halffloat", sizeof(permutationname));
}
vertstrings_list[vertstrings_count++] = vertstring ? vertstring : builtinshader_light_vert;
fragstrings_list[fragstrings_count++] = fragstring ? fragstring : builtinshader_light_frag;
r_shadow_program_light[i] = GL_Backend_CompileProgram(vertstrings_count, vertstrings_list, fragstrings_count, fragstrings_list);
if (!r_shadow_program_light[i])
{
- Con_Printf("permutation %s %s %s %s %s %s failed for shader %s, some features may not work properly!\n", i & 1 ? "specular" : "", i & 2 ? "fog" : "", i & 4 ? "cubefilter" : "", i & 8 ? "offsetmapping" : "", i & 16 ? "surfacenormalize" : "", i & 32 ? "geforcefx" : "", "glsl/light");
+ Con_Printf("permutation%s failed for shader %s, some features may not work properly!\n", permutationname, "glsl/light");
continue;
}
qglUseProgramObjectARB(r_shadow_program_light[i]);
{
qglUniform1iARB(qglGetUniformLocationARB(r_shadow_program_light[i], "Texture_FogMask"), 4);CHECKGLERROR
}
+ qglUniform1iARB(qglGetUniformLocationARB(r_shadow_program_light[i], "Texture_Pants"), 5);CHECKGLERROR
+ qglUniform1iARB(qglGetUniformLocationARB(r_shadow_program_light[i], "Texture_Shirt"), 6);CHECKGLERROR
}
qglUseProgramObjectARB(0);
if (fragstring)
R_Mesh_TexBind(2, R_GetTexture(r_texture_white)); // gloss
R_Mesh_TexBindCubeMap(3, R_GetTexture(r_shadow_rtlight->currentcubemap)); // light filter
R_Mesh_TexBind(4, R_GetTexture(r_texture_fogattenuation)); // fog
+ R_Mesh_TexBind(5, R_GetTexture(r_texture_white)); // pants
+ R_Mesh_TexBind(6, R_GetTexture(r_texture_white)); // shirt
//R_Mesh_TexMatrix(3, r_shadow_entitytolight); // light filter matrix
GL_BlendFunc(GL_ONE, GL_ONE);
GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 0);
CHECKGLERROR
- r_shadow_lightpermutation = 0;
- // only add a feature to the permutation if that permutation exists
- // (otherwise it might end up not using a shader at all, which looks
- // worse than using less features)
- if (fogenabled && r_shadow_program_light[r_shadow_lightpermutation | SHADERPERMUTATION_FOG])
- r_shadow_lightpermutation |= SHADERPERMUTATION_FOG;
- if (r_shadow_rtlight->specularscale && r_shadow_gloss.integer >= 1 && r_shadow_program_light[r_shadow_lightpermutation | SHADERPERMUTATION_SPECULAR])
- r_shadow_lightpermutation |= SHADERPERMUTATION_SPECULAR;
- if (r_shadow_rtlight->currentcubemap != r_texture_whitecube && r_shadow_program_light[r_shadow_lightpermutation | SHADERPERMUTATION_CUBEFILTER])
- r_shadow_lightpermutation |= SHADERPERMUTATION_CUBEFILTER;
- if (r_shadow_glsl_offsetmapping.integer && r_shadow_program_light[r_shadow_lightpermutation | SHADERPERMUTATION_OFFSETMAPPING])
- r_shadow_lightpermutation |= SHADERPERMUTATION_OFFSETMAPPING;
- if (r_shadow_glsl_surfacenormalize.integer && r_shadow_program_light[r_shadow_lightpermutation | SHADERPERMUTATION_SURFACENORMALIZE])
- r_shadow_lightpermutation |= SHADERPERMUTATION_SURFACENORMALIZE;
- if (r_shadow_glsl_usehalffloat.integer && r_shadow_program_light[r_shadow_lightpermutation | SHADERPERMUTATION_GEFORCEFX])
- r_shadow_lightpermutation |= SHADERPERMUTATION_GEFORCEFX;
- r_shadow_lightprog = r_shadow_program_light[r_shadow_lightpermutation];
- qglUseProgramObjectARB(r_shadow_lightprog);CHECKGLERROR
- // TODO: support fog (after renderer is converted to texture fog)
- if (r_shadow_lightpermutation & SHADERPERMUTATION_FOG)
- {
- qglUniform1fARB(qglGetUniformLocationARB(r_shadow_lightprog, "FogRangeRecip"), fograngerecip);CHECKGLERROR
- }
- qglUniform1fARB(qglGetUniformLocationARB(r_shadow_lightprog, "AmbientScale"), r_shadow_rtlight->ambientscale);CHECKGLERROR
- qglUniform1fARB(qglGetUniformLocationARB(r_shadow_lightprog, "DiffuseScale"), r_shadow_rtlight->diffusescale);CHECKGLERROR
- if (r_shadow_lightpermutation & SHADERPERMUTATION_SPECULAR)
- {
- qglUniform1fARB(qglGetUniformLocationARB(r_shadow_lightprog, "SpecularPower"), 8);CHECKGLERROR
- qglUniform1fARB(qglGetUniformLocationARB(r_shadow_lightprog, "SpecularScale"), r_shadow_rtlight->specularscale);CHECKGLERROR
- }
- //qglUniform3fARB(qglGetUniformLocationARB(r_shadow_lightprog, "LightColor"), r_shadow_entitylightcolorbase[0], r_shadow_entitylightcolorbase[1], r_shadow_entitylightcolorbase[2]);CHECKGLERROR
- //qglUniform3fARB(qglGetUniformLocationARB(r_shadow_lightprog, "LightPosition"), relativelightorigin[0], relativelightorigin[1], relativelightorigin[2]);CHECKGLERROR
- //if (r_shadow_lightpermutation & (SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_FOG | SHADERPERMUTATION_OFFSETMAPPING))
- //{
- // qglUniform3fARB(qglGetUniformLocationARB(r_shadow_lightprog, "EyePosition"), relativeeyeorigin[0], relativeeyeorigin[1], relativeeyeorigin[2]);CHECKGLERROR
- //}
- if (r_shadow_lightpermutation & SHADERPERMUTATION_OFFSETMAPPING)
- {
- qglUniform1fARB(qglGetUniformLocationARB(r_shadow_lightprog, "OffsetMapping_Scale"), r_shadow_glsl_offsetmapping_scale.value);CHECKGLERROR
- qglUniform1fARB(qglGetUniformLocationARB(r_shadow_lightprog, "OffsetMapping_Bias"), r_shadow_glsl_offsetmapping_bias.value);CHECKGLERROR
- }
}
}
extern float *rsurface_normal3f;
extern void RSurf_SetVertexPointer(const entity_render_t *ent, const texture_t *texture, const msurface_t *surface, const vec3_t modelorg);
-static void R_Shadow_RenderSurfacesLighting_Light_Vertex_Shading(const msurface_t *surface, const float *diffusecolor, const float *ambientcolor, float reduce)
+static void R_Shadow_RenderSurfacesLighting_Light_Vertex_Shading(const msurface_t *surface, const float *diffusecolor, const float *ambientcolor)
{
int numverts = surface->num_vertices;
float *vertex3f = rsurface_vertex3f + 3 * surface->num_firstvertex;
if ((dot = DotProduct(n, v)) < 0)
{
shadeintensity = -dot / sqrt(VectorLength2(v) * VectorLength2(n));
- color4f[0] = (ambientcolor[0] + shadeintensity * diffusecolor[0]) - reduce;
- color4f[1] = (ambientcolor[1] + shadeintensity * diffusecolor[1]) - reduce;
- color4f[2] = (ambientcolor[2] + shadeintensity * diffusecolor[2]) - reduce;
+ color4f[0] = (ambientcolor[0] + shadeintensity * diffusecolor[0]);
+ color4f[1] = (ambientcolor[1] + shadeintensity * diffusecolor[1]);
+ color4f[2] = (ambientcolor[2] + shadeintensity * diffusecolor[2]);
if (fogenabled)
{
float f = VERTEXFOGTABLE(VectorDistance(v, r_shadow_entityeyeorigin));
if ((dot = DotProduct(n, v)) < 0)
{
shadeintensity = -dot / sqrt(VectorLength2(v) * VectorLength2(n));
- color4f[0] = (ambientcolor[0] + shadeintensity * diffusecolor[0]) * distintensity - reduce;
- color4f[1] = (ambientcolor[1] + shadeintensity * diffusecolor[1]) * distintensity - reduce;
- color4f[2] = (ambientcolor[2] + shadeintensity * diffusecolor[2]) * distintensity - reduce;
+ color4f[0] = (ambientcolor[0] + shadeintensity * diffusecolor[0]) * distintensity;
+ color4f[1] = (ambientcolor[1] + shadeintensity * diffusecolor[1]) * distintensity;
+ color4f[2] = (ambientcolor[2] + shadeintensity * diffusecolor[2]) * distintensity;
}
else
{
- color4f[0] = ambientcolor[0] * distintensity - reduce;
- color4f[1] = ambientcolor[1] * distintensity - reduce;
- color4f[2] = ambientcolor[2] * distintensity - reduce;
+ color4f[0] = ambientcolor[0] * distintensity;
+ color4f[1] = ambientcolor[1] * distintensity;
+ color4f[2] = ambientcolor[2] * distintensity;
}
if (fogenabled)
{
if ((dot = DotProduct(n, v)) < 0)
{
shadeintensity = -dot / sqrt(VectorLength2(v) * VectorLength2(n));
- color4f[0] = (ambientcolor[0] + shadeintensity * diffusecolor[0]) * distintensity - reduce;
- color4f[1] = (ambientcolor[1] + shadeintensity * diffusecolor[1]) * distintensity - reduce;
- color4f[2] = (ambientcolor[2] + shadeintensity * diffusecolor[2]) * distintensity - reduce;
+ color4f[0] = (ambientcolor[0] + shadeintensity * diffusecolor[0]) * distintensity;
+ color4f[1] = (ambientcolor[1] + shadeintensity * diffusecolor[1]) * distintensity;
+ color4f[2] = (ambientcolor[2] + shadeintensity * diffusecolor[2]) * distintensity;
}
else
{
- color4f[0] = ambientcolor[0] * distintensity - reduce;
- color4f[1] = ambientcolor[1] * distintensity - reduce;
- color4f[2] = ambientcolor[2] * distintensity - reduce;
+ color4f[0] = ambientcolor[0] * distintensity;
+ color4f[1] = ambientcolor[1] * distintensity;
+ color4f[2] = ambientcolor[2] * distintensity;
}
if (fogenabled)
{
}
}
-static void R_Shadow_RenderSurfacesLighting_VisibleLighting(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)
+static void R_Shadow_RenderSurfacesLighting_VisibleLighting(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)
{
// used to display how many times a surface is lit for level design purposes
int surfacelistindex;
rmeshstate_t m;
- qboolean doambientbase = r_shadow_rtlight->ambientscale * VectorLength2(lightcolorbase) > 0.00001 && basetexture != r_texture_black;
- qboolean dodiffusebase = r_shadow_rtlight->diffusescale * VectorLength2(lightcolorbase) > 0.00001 && basetexture != r_texture_black;
- qboolean doambientpants = r_shadow_rtlight->ambientscale * VectorLength2(lightcolorpants) > 0.00001 && pantstexture != r_texture_black;
- qboolean dodiffusepants = r_shadow_rtlight->diffusescale * VectorLength2(lightcolorpants) > 0.00001 && pantstexture != r_texture_black;
- qboolean doambientshirt = r_shadow_rtlight->ambientscale * VectorLength2(lightcolorshirt) > 0.00001 && shirttexture != r_texture_black;
- qboolean dodiffuseshirt = r_shadow_rtlight->diffusescale * VectorLength2(lightcolorshirt) > 0.00001 && shirttexture != r_texture_black;
- qboolean dospecular = specularscale * VectorLength2(lightcolorbase) > 0.00001 && glosstexture != r_texture_black;
- if (!doambientbase && !dodiffusebase && !doambientpants && !dodiffusepants && !doambientshirt && !dodiffuseshirt && !dospecular)
- return;
GL_Color(0.1, 0.025, 0, 1);
memset(&m, 0, sizeof(m));
R_Mesh_State(&m);
}
}
-static void R_Shadow_RenderSurfacesLighting_Light_GLSL(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)
+static void R_Shadow_RenderSurfacesLighting_Light_GLSL(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)
{
// ARB2 GLSL shader path (GFFX5200, Radeon 9500)
int surfacelistindex;
- qboolean dobase = (r_shadow_rtlight->ambientscale + r_shadow_rtlight->diffusescale) * VectorLength2(lightcolorbase) > 0.00001 && basetexture != r_texture_black;
- qboolean dopants = (r_shadow_rtlight->ambientscale + r_shadow_rtlight->diffusescale) * VectorLength2(lightcolorpants) > 0.00001 && pantstexture != r_texture_black;
- qboolean doshirt = (r_shadow_rtlight->ambientscale + r_shadow_rtlight->diffusescale) * VectorLength2(lightcolorshirt) > 0.00001 && shirttexture != r_texture_black;
- qboolean dospecular = specularscale * VectorLength2(lightcolorbase) > 0.00001 && glosstexture != r_texture_black;
- // TODO: add direct pants/shirt rendering
- if (dopants)
- R_Shadow_RenderSurfacesLighting_Light_GLSL(ent, texture, numsurfaces, surfacelist, lightcolorpants, vec3_origin, vec3_origin, pantstexture, r_texture_black, r_texture_black, normalmaptexture, r_texture_black, 0);
- if (doshirt)
- R_Shadow_RenderSurfacesLighting_Light_GLSL(ent, texture, numsurfaces, surfacelist, lightcolorshirt, vec3_origin, vec3_origin, shirttexture, r_texture_black, r_texture_black, normalmaptexture, r_texture_black, 0);
- if (!dobase && !dospecular)
- return;
+ // select a permutation of the lighting shader appropriate to this
+ // combination of texture, entity, light source, and fogging, only use the
+ // minimum features necessary to avoid wasting rendering time in the
+ // fragment shader on features that are not being used
+ r_shadow_lightpermutation = 0;
+ // only add a feature to the permutation if that permutation exists
+ // (otherwise it might end up not using a shader at all, which looks
+ // worse than using less features)
+ if (fogenabled && r_shadow_program_light[r_shadow_lightpermutation | SHADERPERMUTATION_FOG])
+ r_shadow_lightpermutation |= SHADERPERMUTATION_FOG;
+ if ((dopants || doshirt) && r_shadow_program_light[r_shadow_lightpermutation | SHADERPERMUTATION_COLORMAPPING])
+ r_shadow_lightpermutation |= SHADERPERMUTATION_COLORMAPPING;
+ if (specularscale > 0 && r_shadow_program_light[r_shadow_lightpermutation | SHADERPERMUTATION_SPECULAR])
+ r_shadow_lightpermutation |= SHADERPERMUTATION_SPECULAR;
+ if (r_shadow_rtlight->currentcubemap != r_texture_whitecube && r_shadow_program_light[r_shadow_lightpermutation | SHADERPERMUTATION_CUBEFILTER])
+ r_shadow_lightpermutation |= SHADERPERMUTATION_CUBEFILTER;
+ if (r_shadow_glsl_offsetmapping.integer && r_shadow_program_light[r_shadow_lightpermutation | SHADERPERMUTATION_OFFSETMAPPING])
+ r_shadow_lightpermutation |= SHADERPERMUTATION_OFFSETMAPPING;
+ if (r_shadow_glsl_surfacenormalize.integer && r_shadow_program_light[r_shadow_lightpermutation | SHADERPERMUTATION_SURFACENORMALIZE])
+ r_shadow_lightpermutation |= SHADERPERMUTATION_SURFACENORMALIZE;
+ if (r_shadow_glsl_usehalffloat.integer && r_shadow_program_light[r_shadow_lightpermutation | SHADERPERMUTATION_GEFORCEFX])
+ r_shadow_lightpermutation |= SHADERPERMUTATION_GEFORCEFX;
+ r_shadow_lightprog = r_shadow_program_light[r_shadow_lightpermutation];
+ qglUseProgramObjectARB(r_shadow_lightprog);CHECKGLERROR
R_Mesh_TexMatrix(0, &texture->currenttexmatrix);
+ R_Mesh_TexMatrix(3, &r_shadow_entitytolight);
R_Mesh_TexBind(0, R_GetTexture(normalmaptexture));
R_Mesh_TexBind(1, R_GetTexture(basetexture));
- R_Mesh_TexBind(2, R_GetTexture(glosstexture));
+ qglUniform3fARB(qglGetUniformLocationARB(r_shadow_lightprog, "LightPosition"), r_shadow_entitylightorigin[0], r_shadow_entitylightorigin[1], r_shadow_entitylightorigin[2]);CHECKGLERROR
+ if (r_shadow_lightpermutation & (SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_FOG | SHADERPERMUTATION_OFFSETMAPPING))
+ {
+ qglUniform3fARB(qglGetUniformLocationARB(r_shadow_lightprog, "EyePosition"), r_shadow_entityeyeorigin[0], r_shadow_entityeyeorigin[1], r_shadow_entityeyeorigin[2]);CHECKGLERROR
+ }
+ qglUniform3fARB(qglGetUniformLocationARB(r_shadow_lightprog, "LightColor"), lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);CHECKGLERROR
+ if (r_shadow_lightpermutation & SHADERPERMUTATION_COLORMAPPING)
+ {
+ R_Mesh_TexBind(5, R_GetTexture(pantstexture));
+ R_Mesh_TexBind(6, R_GetTexture(shirttexture));
+ qglUniform3fARB(qglGetUniformLocationARB(r_shadow_lightprog, "Color_Pants"), ent->colormap_pantscolor[0], ent->colormap_pantscolor[1], ent->colormap_pantscolor[2]);CHECKGLERROR
+ qglUniform3fARB(qglGetUniformLocationARB(r_shadow_lightprog, "Color_Shirt"), ent->colormap_shirtcolor[0], ent->colormap_shirtcolor[1], ent->colormap_shirtcolor[2]);CHECKGLERROR
+ }
+ if (r_shadow_lightpermutation & SHADERPERMUTATION_FOG)
+ {
+ qglUniform1fARB(qglGetUniformLocationARB(r_shadow_lightprog, "FogRangeRecip"), fograngerecip);CHECKGLERROR
+ }
+ qglUniform1fARB(qglGetUniformLocationARB(r_shadow_lightprog, "AmbientScale"), r_shadow_rtlight->ambientscale);CHECKGLERROR
+ qglUniform1fARB(qglGetUniformLocationARB(r_shadow_lightprog, "DiffuseScale"), r_shadow_rtlight->diffusescale);CHECKGLERROR
if (r_shadow_lightpermutation & SHADERPERMUTATION_SPECULAR)
{
+ R_Mesh_TexBind(2, R_GetTexture(glosstexture));
+ qglUniform1fARB(qglGetUniformLocationARB(r_shadow_lightprog, "SpecularPower"), 8);CHECKGLERROR
qglUniform1fARB(qglGetUniformLocationARB(r_shadow_lightprog, "SpecularScale"), specularscale);CHECKGLERROR
}
- qglUniform3fARB(qglGetUniformLocationARB(r_shadow_lightprog, "LightColor"), lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);CHECKGLERROR
+ if (r_shadow_lightpermutation & SHADERPERMUTATION_OFFSETMAPPING)
+ {
+ qglUniform1fARB(qglGetUniformLocationARB(r_shadow_lightprog, "OffsetMapping_Scale"), r_shadow_glsl_offsetmapping_scale.value);CHECKGLERROR
+ qglUniform1fARB(qglGetUniformLocationARB(r_shadow_lightprog, "OffsetMapping_Bias"), r_shadow_glsl_offsetmapping_bias.value);CHECKGLERROR
+ }
for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++)
{
const msurface_t *surface = surfacelist[surfacelistindex];
}
}
-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)
+static void R_Shadow_RenderSurfacesLighting_Light_Dot3_AmbientPass(const entity_render_t *ent, const texture_t *texture, const msurface_t *surface, const vec3_t lightcolorbase, rtexture_t *basetexture, float colorscale)
{
- // ARB path (any Geforce, any Radeon)
- int surfacelistindex;
int renders;
- float color2[3], colorscale;
+ float color2[3];
rmeshstate_t m;
- qboolean doambientbase = r_shadow_rtlight->ambientscale * VectorLength2(lightcolorbase) > 0.00001 && basetexture != r_texture_black;
- qboolean dodiffusebase = r_shadow_rtlight->diffusescale * VectorLength2(lightcolorbase) > 0.00001 && basetexture != r_texture_black;
- qboolean doambientpants = r_shadow_rtlight->ambientscale * VectorLength2(lightcolorpants) > 0.00001 && pantstexture != r_texture_black;
- qboolean dodiffusepants = r_shadow_rtlight->diffusescale * VectorLength2(lightcolorpants) > 0.00001 && pantstexture != r_texture_black;
- qboolean doambientshirt = r_shadow_rtlight->ambientscale * VectorLength2(lightcolorshirt) > 0.00001 && shirttexture != r_texture_black;
- qboolean dodiffuseshirt = r_shadow_rtlight->diffusescale * VectorLength2(lightcolorshirt) > 0.00001 && shirttexture != r_texture_black;
- qboolean dospecular = specularscale * VectorLength2(lightcolorbase) > 0.00001 && glosstexture != r_texture_black;
- // TODO: add direct pants/shirt rendering
- if (doambientpants || dodiffusepants)
- R_Shadow_RenderSurfacesLighting_Light_Dot3(ent, texture, numsurfaces, surfacelist, lightcolorpants, vec3_origin, vec3_origin, pantstexture, r_texture_black, r_texture_black, normalmaptexture, r_texture_black, 0);
- if (doambientshirt || dodiffuseshirt)
- R_Shadow_RenderSurfacesLighting_Light_Dot3(ent, texture, numsurfaces, surfacelist, lightcolorshirt, vec3_origin, vec3_origin, shirttexture, r_texture_black, r_texture_black, normalmaptexture, r_texture_black, 0);
- if (!doambientbase && !dodiffusebase && !dospecular)
- return;
- for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++)
+ const int *elements = surface->groupmesh->data_element3i + surface->num_firsttriangle * 3;
+ GL_Color(1,1,1,1);
+ // colorscale accounts for how much we multiply the brightness
+ // during combine.
+ //
+ // mult is how many times the final pass of the lighting will be
+ // performed to get more brightness than otherwise possible.
+ //
+ // Limit mult to 64 for sanity sake.
+ if (r_shadow_texture3d.integer && r_shadow_rtlight->currentcubemap != r_texture_whitecube && r_textureunits.integer >= 4)
{
- const msurface_t *surface = surfacelist[surfacelistindex];
- const int *elements = surface->groupmesh->data_element3i + surface->num_firsttriangle * 3;
- 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 (doambientbase)
- {
- GL_Color(1,1,1,1);
- colorscale = r_shadow_rtlight->ambientscale;
- // colorscale accounts for how much we multiply the brightness
- // during combine.
- //
- // mult is how many times the final pass of the lighting will be
- // performed to get more brightness than otherwise possible.
- //
- // Limit mult to 64 for sanity sake.
- if (r_shadow_texture3d.integer && r_shadow_rtlight->currentcubemap != r_texture_whitecube && r_textureunits.integer >= 4)
- {
- // 3 3D combine path (Geforce3, Radeon 8500)
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex3d[0] = R_GetTexture(r_shadow_attenuation3dtexture);
+ // 3 3D combine path (Geforce3, Radeon 8500)
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex3d[0] = R_GetTexture(r_shadow_attenuation3dtexture);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[0] = rsurface_vertex3f;
- m.texmatrix[0] = r_shadow_entitytoattenuationxyz;
+ m.pointer_texcoord3f[0] = rsurface_vertex3f;
+ m.texmatrix[0] = r_shadow_entitytoattenuationxyz;
#else
- m.pointer_texcoord3f[0] = varray_texcoord3f[0];
- R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[0] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
+ m.pointer_texcoord3f[0] = varray_texcoord3f[0];
+ R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[0] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
#endif
- m.tex[1] = R_GetTexture(basetexture);
- m.pointer_texcoord[1] = surface->groupmesh->data_texcoordtexture2f;
- m.texmatrix[1] = texture->currenttexmatrix;
- m.texcubemap[2] = R_GetTexture(r_shadow_rtlight->currentcubemap);
+ m.tex[1] = R_GetTexture(basetexture);
+ m.pointer_texcoord[1] = surface->groupmesh->data_texcoordtexture2f;
+ m.texmatrix[1] = texture->currenttexmatrix;
+ m.texcubemap[2] = R_GetTexture(r_shadow_rtlight->currentcubemap);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[2] = rsurface_vertex3f;
- m.texmatrix[2] = r_shadow_entitytolight;
+ m.pointer_texcoord3f[2] = rsurface_vertex3f;
+ m.texmatrix[2] = r_shadow_entitytolight;
#else
- m.pointer_texcoord3f[2] = varray_texcoord3f[2];
- R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[2] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytolight);
+ m.pointer_texcoord3f[2] = varray_texcoord3f[2];
+ R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[2] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytolight);
#endif
- GL_BlendFunc(GL_ONE, GL_ONE);
- }
- else if (r_shadow_texture3d.integer && r_shadow_rtlight->currentcubemap == r_texture_whitecube && r_textureunits.integer >= 2)
- {
- // 2 3D combine path (Geforce3, original Radeon)
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex3d[0] = R_GetTexture(r_shadow_attenuation3dtexture);
+ GL_BlendFunc(GL_ONE, GL_ONE);
+ }
+ else if (r_shadow_texture3d.integer && r_shadow_rtlight->currentcubemap == r_texture_whitecube && r_textureunits.integer >= 2)
+ {
+ // 2 3D combine path (Geforce3, original Radeon)
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex3d[0] = R_GetTexture(r_shadow_attenuation3dtexture);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[0] = rsurface_vertex3f;
- m.texmatrix[0] = r_shadow_entitytoattenuationxyz;
+ m.pointer_texcoord3f[0] = rsurface_vertex3f;
+ m.texmatrix[0] = r_shadow_entitytoattenuationxyz;
#else
- m.pointer_texcoord3f[0] = varray_texcoord3f[0];
- R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[0] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
+ m.pointer_texcoord3f[0] = varray_texcoord3f[0];
+ R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[0] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
#endif
- m.tex[1] = R_GetTexture(basetexture);
- m.pointer_texcoord[1] = surface->groupmesh->data_texcoordtexture2f;
- m.texmatrix[1] = texture->currenttexmatrix;
- GL_BlendFunc(GL_ONE, GL_ONE);
- }
- else if (r_textureunits.integer >= 4 && r_shadow_rtlight->currentcubemap != r_texture_whitecube)
- {
- // 4 2D combine path (Geforce3, Radeon 8500)
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex[0] = R_GetTexture(r_shadow_attenuation2dtexture);
+ m.tex[1] = R_GetTexture(basetexture);
+ m.pointer_texcoord[1] = surface->groupmesh->data_texcoordtexture2f;
+ m.texmatrix[1] = texture->currenttexmatrix;
+ GL_BlendFunc(GL_ONE, GL_ONE);
+ }
+ else if (r_textureunits.integer >= 4 && r_shadow_rtlight->currentcubemap != r_texture_whitecube)
+ {
+ // 4 2D combine path (Geforce3, Radeon 8500)
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex[0] = R_GetTexture(r_shadow_attenuation2dtexture);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[0] = rsurface_vertex3f;
- m.texmatrix[0] = r_shadow_entitytoattenuationxyz;
+ m.pointer_texcoord3f[0] = rsurface_vertex3f;
+ m.texmatrix[0] = r_shadow_entitytoattenuationxyz;
#else
- m.pointer_texcoord[0] = varray_texcoord2f[0];
- R_Shadow_Transform_Vertex3f_Texcoord2f(varray_texcoord2f[0] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
+ m.pointer_texcoord[0] = varray_texcoord2f[0];
+ R_Shadow_Transform_Vertex3f_Texcoord2f(varray_texcoord2f[0] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
#endif
- m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture);
+ m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[1] = rsurface_vertex3f;
- m.texmatrix[1] = r_shadow_entitytoattenuationz;
+ m.pointer_texcoord3f[1] = rsurface_vertex3f;
+ m.texmatrix[1] = r_shadow_entitytoattenuationz;
#else
- m.pointer_texcoord[1] = varray_texcoord2f[1];
- R_Shadow_Transform_Vertex3f_Texcoord2f(varray_texcoord2f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationz);
+ m.pointer_texcoord[1] = varray_texcoord2f[1];
+ R_Shadow_Transform_Vertex3f_Texcoord2f(varray_texcoord2f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationz);
#endif
- m.tex[2] = R_GetTexture(basetexture);
- m.pointer_texcoord[2] = surface->groupmesh->data_texcoordtexture2f;
- m.texmatrix[2] = texture->currenttexmatrix;
- if (r_shadow_rtlight->currentcubemap != r_texture_whitecube)
- {
- m.texcubemap[3] = R_GetTexture(r_shadow_rtlight->currentcubemap);
+ m.tex[2] = R_GetTexture(basetexture);
+ m.pointer_texcoord[2] = surface->groupmesh->data_texcoordtexture2f;
+ m.texmatrix[2] = texture->currenttexmatrix;
+ if (r_shadow_rtlight->currentcubemap != r_texture_whitecube)
+ {
+ m.texcubemap[3] = R_GetTexture(r_shadow_rtlight->currentcubemap);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[3] = rsurface_vertex3f;
- m.texmatrix[3] = r_shadow_entitytolight;
+ m.pointer_texcoord3f[3] = rsurface_vertex3f;
+ m.texmatrix[3] = r_shadow_entitytolight;
#else
- m.pointer_texcoord3f[3] = varray_texcoord3f[3];
- R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[3] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytolight);
+ m.pointer_texcoord3f[3] = varray_texcoord3f[3];
+ R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[3] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytolight);
#endif
- }
- GL_BlendFunc(GL_ONE, GL_ONE);
- }
- else if (r_textureunits.integer >= 3 && r_shadow_rtlight->currentcubemap == r_texture_whitecube)
- {
- // 3 2D combine path (Geforce3, original Radeon)
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex[0] = R_GetTexture(r_shadow_attenuation2dtexture);
+ }
+ GL_BlendFunc(GL_ONE, GL_ONE);
+ }
+ else if (r_textureunits.integer >= 3 && r_shadow_rtlight->currentcubemap == r_texture_whitecube)
+ {
+ // 3 2D combine path (Geforce3, original Radeon)
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex[0] = R_GetTexture(r_shadow_attenuation2dtexture);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[0] = rsurface_vertex3f;
- m.texmatrix[0] = r_shadow_entitytoattenuationxyz;
+ m.pointer_texcoord3f[0] = rsurface_vertex3f;
+ m.texmatrix[0] = r_shadow_entitytoattenuationxyz;
#else
- m.pointer_texcoord[0] = varray_texcoord2f[0];
- R_Shadow_Transform_Vertex3f_Texcoord2f(varray_texcoord2f[0] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
+ m.pointer_texcoord[0] = varray_texcoord2f[0];
+ R_Shadow_Transform_Vertex3f_Texcoord2f(varray_texcoord2f[0] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
#endif
- m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture);
+ m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[1] = rsurface_vertex3f;
- m.texmatrix[1] = r_shadow_entitytoattenuationz;
+ m.pointer_texcoord3f[1] = rsurface_vertex3f;
+ m.texmatrix[1] = r_shadow_entitytoattenuationz;
#else
- m.pointer_texcoord[1] = varray_texcoord2f[1];
- R_Shadow_Transform_Vertex3f_Texcoord2f(varray_texcoord2f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationz);
+ m.pointer_texcoord[1] = varray_texcoord2f[1];
+ R_Shadow_Transform_Vertex3f_Texcoord2f(varray_texcoord2f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationz);
#endif
- m.tex[2] = R_GetTexture(basetexture);
- m.pointer_texcoord[2] = surface->groupmesh->data_texcoordtexture2f;
- m.texmatrix[2] = texture->currenttexmatrix;
- GL_BlendFunc(GL_ONE, GL_ONE);
- }
- else
- {
- // 2/2/2 2D combine path (any dot3 card)
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex[0] = R_GetTexture(r_shadow_attenuation2dtexture);
+ m.tex[2] = R_GetTexture(basetexture);
+ m.pointer_texcoord[2] = surface->groupmesh->data_texcoordtexture2f;
+ m.texmatrix[2] = texture->currenttexmatrix;
+ GL_BlendFunc(GL_ONE, GL_ONE);
+ }
+ else
+ {
+ // 2/2/2 2D combine path (any dot3 card)
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex[0] = R_GetTexture(r_shadow_attenuation2dtexture);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[0] = rsurface_vertex3f;
- m.texmatrix[0] = r_shadow_entitytoattenuationxyz;
+ m.pointer_texcoord3f[0] = rsurface_vertex3f;
+ m.texmatrix[0] = r_shadow_entitytoattenuationxyz;
#else
- m.pointer_texcoord[0] = varray_texcoord2f[0];
- R_Shadow_Transform_Vertex3f_Texcoord2f(varray_texcoord2f[0] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
+ m.pointer_texcoord[0] = varray_texcoord2f[0];
+ R_Shadow_Transform_Vertex3f_Texcoord2f(varray_texcoord2f[0] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
#endif
- m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture);
+ m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[1] = rsurface_vertex3f;
- m.texmatrix[1] = r_shadow_entitytoattenuationz;
+ m.pointer_texcoord3f[1] = rsurface_vertex3f;
+ m.texmatrix[1] = r_shadow_entitytoattenuationz;
#else
- m.pointer_texcoord[1] = varray_texcoord2f[1];
- R_Shadow_Transform_Vertex3f_Texcoord2f(varray_texcoord2f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationz);
+ m.pointer_texcoord[1] = varray_texcoord2f[1];
+ R_Shadow_Transform_Vertex3f_Texcoord2f(varray_texcoord2f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationz);
#endif
- R_Mesh_State(&m);
- GL_ColorMask(0,0,0,1);
- GL_BlendFunc(GL_ONE, GL_ZERO);
- 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);
+ R_Mesh_State(&m);
+ GL_ColorMask(0,0,0,1);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ 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);
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex[0] = R_GetTexture(basetexture);
- m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
- m.texmatrix[0] = texture->currenttexmatrix;
- if (r_shadow_rtlight->currentcubemap != r_texture_whitecube)
- {
- m.texcubemap[1] = R_GetTexture(r_shadow_rtlight->currentcubemap);
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex[0] = R_GetTexture(basetexture);
+ m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
+ m.texmatrix[0] = texture->currenttexmatrix;
+ if (r_shadow_rtlight->currentcubemap != r_texture_whitecube)
+ {
+ m.texcubemap[1] = R_GetTexture(r_shadow_rtlight->currentcubemap);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[1] = rsurface_vertex3f;
- m.texmatrix[1] = r_shadow_entitytolight;
+ m.pointer_texcoord3f[1] = rsurface_vertex3f;
+ m.texmatrix[1] = r_shadow_entitytolight;
#else
- m.pointer_texcoord3f[1] = varray_texcoord3f[1];
- R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytolight);
+ m.pointer_texcoord3f[1] = varray_texcoord3f[1];
+ R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytolight);
#endif
- }
- GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
- }
- // this final code is shared
- 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);
}
- if (dodiffusebase)
- {
- GL_Color(1,1,1,1);
- colorscale = r_shadow_rtlight->diffusescale;
- // colorscale accounts for how much we multiply the brightness
- // during combine.
- //
- // mult is how many times the final pass of the lighting will be
- // performed to get more brightness than otherwise possible.
- //
- // Limit mult to 64 for sanity sake.
- if (r_shadow_texture3d.integer && r_textureunits.integer >= 4)
- {
- // 3/2 3D combine path (Geforce3, Radeon 8500)
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex[0] = R_GetTexture(normalmaptexture);
- m.texcombinergb[0] = GL_REPLACE;
- m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
- m.texmatrix[0] = texture->currenttexmatrix;
- m.texcubemap[1] = R_GetTexture(r_texture_normalizationcube);
- m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
- m.pointer_texcoord3f[1] = varray_texcoord3f[1];
- R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, rsurface_svector3f + 3 * surface->num_firstvertex, rsurface_tvector3f + 3 * surface->num_firstvertex, rsurface_normal3f + 3 * surface->num_firstvertex, r_shadow_entitylightorigin);
- m.tex3d[2] = R_GetTexture(r_shadow_attenuation3dtexture);
+ GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
+ }
+ // this final code is shared
+ 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_DiffusePass(const entity_render_t *ent, const texture_t *texture, const msurface_t *surface, const vec3_t lightcolorbase, rtexture_t *basetexture, rtexture_t *normalmaptexture, float colorscale)
+{
+ int renders;
+ float color2[3];
+ rmeshstate_t m;
+ const int *elements = surface->groupmesh->data_element3i + surface->num_firsttriangle * 3;
+ GL_Color(1,1,1,1);
+ // colorscale accounts for how much we multiply the brightness
+ // during combine.
+ //
+ // mult is how many times the final pass of the lighting will be
+ // performed to get more brightness than otherwise possible.
+ //
+ // Limit mult to 64 for sanity sake.
+ if (r_shadow_texture3d.integer && r_textureunits.integer >= 4)
+ {
+ // 3/2 3D combine path (Geforce3, Radeon 8500)
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex[0] = R_GetTexture(normalmaptexture);
+ m.texcombinergb[0] = GL_REPLACE;
+ m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
+ m.texmatrix[0] = texture->currenttexmatrix;
+ m.texcubemap[1] = R_GetTexture(r_texture_normalizationcube);
+ m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
+ m.pointer_texcoord3f[1] = varray_texcoord3f[1];
+ R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, rsurface_svector3f + 3 * surface->num_firstvertex, rsurface_tvector3f + 3 * surface->num_firstvertex, rsurface_normal3f + 3 * surface->num_firstvertex, r_shadow_entitylightorigin);
+ m.tex3d[2] = R_GetTexture(r_shadow_attenuation3dtexture);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[2] = rsurface_vertex3f;
- m.texmatrix[2] = r_shadow_entitytoattenuationxyz;
+ m.pointer_texcoord3f[2] = rsurface_vertex3f;
+ m.texmatrix[2] = r_shadow_entitytoattenuationxyz;
#else
- m.pointer_texcoord3f[2] = varray_texcoord3f[2];
- R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[2] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
+ m.pointer_texcoord3f[2] = varray_texcoord3f[2];
+ R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[2] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
#endif
- R_Mesh_State(&m);
- GL_ColorMask(0,0,0,1);
- GL_BlendFunc(GL_ONE, GL_ZERO);
- 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);
+ R_Mesh_State(&m);
+ GL_ColorMask(0,0,0,1);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ 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);
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex[0] = R_GetTexture(basetexture);
- m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
- m.texmatrix[0] = texture->currenttexmatrix;
- if (r_shadow_rtlight->currentcubemap != r_texture_whitecube)
- {
- m.texcubemap[1] = R_GetTexture(r_shadow_rtlight->currentcubemap);
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex[0] = R_GetTexture(basetexture);
+ m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
+ m.texmatrix[0] = texture->currenttexmatrix;
+ if (r_shadow_rtlight->currentcubemap != r_texture_whitecube)
+ {
+ m.texcubemap[1] = R_GetTexture(r_shadow_rtlight->currentcubemap);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[1] = rsurface_vertex3f;
- m.texmatrix[1] = r_shadow_entitytolight;
+ m.pointer_texcoord3f[1] = rsurface_vertex3f;
+ m.texmatrix[1] = r_shadow_entitytolight;
#else
- m.pointer_texcoord3f[1] = varray_texcoord3f[1];
- R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytolight);
+ m.pointer_texcoord3f[1] = varray_texcoord3f[1];
+ R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytolight);
#endif
- }
- GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
- }
- else if (r_shadow_texture3d.integer && r_textureunits.integer >= 2 && r_shadow_rtlight->currentcubemap != r_texture_whitecube)
- {
- // 1/2/2 3D combine path (original Radeon)
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex3d[0] = R_GetTexture(r_shadow_attenuation3dtexture);
+ }
+ GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
+ }
+ else if (r_shadow_texture3d.integer && r_textureunits.integer >= 2 && r_shadow_rtlight->currentcubemap != r_texture_whitecube)
+ {
+ // 1/2/2 3D combine path (original Radeon)
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex3d[0] = R_GetTexture(r_shadow_attenuation3dtexture);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[0] = rsurface_vertex3f;
- m.texmatrix[0] = r_shadow_entitytoattenuationxyz;
+ m.pointer_texcoord3f[0] = rsurface_vertex3f;
+ m.texmatrix[0] = r_shadow_entitytoattenuationxyz;
#else
- m.pointer_texcoord3f[0] = varray_texcoord3f[0];
- R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[0] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
+ m.pointer_texcoord3f[0] = varray_texcoord3f[0];
+ R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[0] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
#endif
- R_Mesh_State(&m);
- GL_ColorMask(0,0,0,1);
- GL_BlendFunc(GL_ONE, GL_ZERO);
- 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);
+ R_Mesh_State(&m);
+ GL_ColorMask(0,0,0,1);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ 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);
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex[0] = R_GetTexture(normalmaptexture);
- m.texcombinergb[0] = GL_REPLACE;
- m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
- m.texmatrix[0] = texture->currenttexmatrix;
- m.texcubemap[1] = R_GetTexture(r_texture_normalizationcube);
- m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
- m.pointer_texcoord3f[1] = varray_texcoord3f[1];
- R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, rsurface_svector3f + 3 * surface->num_firstvertex, rsurface_tvector3f + 3 * surface->num_firstvertex, rsurface_normal3f + 3 * surface->num_firstvertex, r_shadow_entitylightorigin);
- R_Mesh_State(&m);
- GL_BlendFunc(GL_DST_ALPHA, GL_ZERO);
- 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);
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex[0] = R_GetTexture(normalmaptexture);
+ m.texcombinergb[0] = GL_REPLACE;
+ m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
+ m.texmatrix[0] = texture->currenttexmatrix;
+ m.texcubemap[1] = R_GetTexture(r_texture_normalizationcube);
+ m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
+ m.pointer_texcoord3f[1] = varray_texcoord3f[1];
+ R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, rsurface_svector3f + 3 * surface->num_firstvertex, rsurface_tvector3f + 3 * surface->num_firstvertex, rsurface_normal3f + 3 * surface->num_firstvertex, r_shadow_entitylightorigin);
+ R_Mesh_State(&m);
+ GL_BlendFunc(GL_DST_ALPHA, GL_ZERO);
+ 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);
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex[0] = R_GetTexture(basetexture);
- m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
- m.texmatrix[0] = texture->currenttexmatrix;
- if (r_shadow_rtlight->currentcubemap != r_texture_whitecube)
- {
- m.texcubemap[1] = R_GetTexture(r_shadow_rtlight->currentcubemap);
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex[0] = R_GetTexture(basetexture);
+ m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
+ m.texmatrix[0] = texture->currenttexmatrix;
+ if (r_shadow_rtlight->currentcubemap != r_texture_whitecube)
+ {
+ m.texcubemap[1] = R_GetTexture(r_shadow_rtlight->currentcubemap);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[1] = rsurface_vertex3f;
- m.texmatrix[1] = r_shadow_entitytolight;
+ m.pointer_texcoord3f[1] = rsurface_vertex3f;
+ m.texmatrix[1] = r_shadow_entitytolight;
#else
- m.pointer_texcoord3f[1] = varray_texcoord3f[1];
- R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytolight);
+ m.pointer_texcoord3f[1] = varray_texcoord3f[1];
+ R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytolight);
#endif
- }
- GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
- }
- else if (r_shadow_texture3d.integer && r_textureunits.integer >= 2 && r_shadow_rtlight->currentcubemap == r_texture_whitecube)
- {
- // 2/2 3D combine path (original Radeon)
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex[0] = R_GetTexture(normalmaptexture);
- m.texcombinergb[0] = GL_REPLACE;
- m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
- m.texmatrix[0] = texture->currenttexmatrix;
- m.texcubemap[1] = R_GetTexture(r_texture_normalizationcube);
- m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
- m.pointer_texcoord3f[1] = varray_texcoord3f[1];
- R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, rsurface_svector3f + 3 * surface->num_firstvertex, rsurface_tvector3f + 3 * surface->num_firstvertex, rsurface_normal3f + 3 * surface->num_firstvertex, r_shadow_entitylightorigin);
- R_Mesh_State(&m);
- GL_ColorMask(0,0,0,1);
- GL_BlendFunc(GL_ONE, GL_ZERO);
- 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);
+ }
+ GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
+ }
+ else if (r_shadow_texture3d.integer && r_textureunits.integer >= 2 && r_shadow_rtlight->currentcubemap == r_texture_whitecube)
+ {
+ // 2/2 3D combine path (original Radeon)
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex[0] = R_GetTexture(normalmaptexture);
+ m.texcombinergb[0] = GL_REPLACE;
+ m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
+ m.texmatrix[0] = texture->currenttexmatrix;
+ m.texcubemap[1] = R_GetTexture(r_texture_normalizationcube);
+ m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
+ m.pointer_texcoord3f[1] = varray_texcoord3f[1];
+ R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, rsurface_svector3f + 3 * surface->num_firstvertex, rsurface_tvector3f + 3 * surface->num_firstvertex, rsurface_normal3f + 3 * surface->num_firstvertex, r_shadow_entitylightorigin);
+ R_Mesh_State(&m);
+ GL_ColorMask(0,0,0,1);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ 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);
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex[0] = R_GetTexture(basetexture);
- m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
- m.texmatrix[0] = texture->currenttexmatrix;
- m.tex3d[1] = R_GetTexture(r_shadow_attenuation3dtexture);
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex[0] = R_GetTexture(basetexture);
+ m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
+ m.texmatrix[0] = texture->currenttexmatrix;
+ m.tex3d[1] = R_GetTexture(r_shadow_attenuation3dtexture);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[1] = rsurface_vertex3f;
- m.texmatrix[1] = r_shadow_entitytoattenuationxyz;
+ m.pointer_texcoord3f[1] = rsurface_vertex3f;
+ m.texmatrix[1] = r_shadow_entitytoattenuationxyz;
#else
- m.pointer_texcoord3f[1] = varray_texcoord3f[1];
- R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
+ m.pointer_texcoord3f[1] = varray_texcoord3f[1];
+ R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
#endif
- GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
- }
- else if (r_textureunits.integer >= 4)
- {
- // 4/2 2D combine path (Geforce3, Radeon 8500)
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex[0] = R_GetTexture(normalmaptexture);
- m.texcombinergb[0] = GL_REPLACE;
- m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
- m.texmatrix[0] = texture->currenttexmatrix;
- m.texcubemap[1] = R_GetTexture(r_texture_normalizationcube);
- m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
- m.pointer_texcoord3f[1] = varray_texcoord3f[1];
- R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, rsurface_svector3f + 3 * surface->num_firstvertex, rsurface_tvector3f + 3 * surface->num_firstvertex, rsurface_normal3f + 3 * surface->num_firstvertex, r_shadow_entitylightorigin);
- m.tex[2] = R_GetTexture(r_shadow_attenuation2dtexture);
+ GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
+ }
+ else if (r_textureunits.integer >= 4)
+ {
+ // 4/2 2D combine path (Geforce3, Radeon 8500)
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex[0] = R_GetTexture(normalmaptexture);
+ m.texcombinergb[0] = GL_REPLACE;
+ m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
+ m.texmatrix[0] = texture->currenttexmatrix;
+ m.texcubemap[1] = R_GetTexture(r_texture_normalizationcube);
+ m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
+ m.pointer_texcoord3f[1] = varray_texcoord3f[1];
+ R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, rsurface_svector3f + 3 * surface->num_firstvertex, rsurface_tvector3f + 3 * surface->num_firstvertex, rsurface_normal3f + 3 * surface->num_firstvertex, r_shadow_entitylightorigin);
+ m.tex[2] = R_GetTexture(r_shadow_attenuation2dtexture);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[2] = rsurface_vertex3f;
- m.texmatrix[2] = r_shadow_entitytoattenuationxyz;
+ m.pointer_texcoord3f[2] = rsurface_vertex3f;
+ m.texmatrix[2] = r_shadow_entitytoattenuationxyz;
#else
- m.pointer_texcoord[2] = varray_texcoord2f[2];
- R_Shadow_Transform_Vertex3f_Texcoord2f(varray_texcoord2f[2] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
+ m.pointer_texcoord[2] = varray_texcoord2f[2];
+ R_Shadow_Transform_Vertex3f_Texcoord2f(varray_texcoord2f[2] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
#endif
- m.tex[3] = R_GetTexture(r_shadow_attenuation2dtexture);
+ m.tex[3] = R_GetTexture(r_shadow_attenuation2dtexture);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[3] = rsurface_vertex3f;
- m.texmatrix[3] = r_shadow_entitytoattenuationz;
+ m.pointer_texcoord3f[3] = rsurface_vertex3f;
+ m.texmatrix[3] = r_shadow_entitytoattenuationz;
#else
- m.pointer_texcoord[3] = varray_texcoord2f[3];
- R_Shadow_Transform_Vertex3f_Texcoord2f(varray_texcoord2f[3] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationz);
+ m.pointer_texcoord[3] = varray_texcoord2f[3];
+ R_Shadow_Transform_Vertex3f_Texcoord2f(varray_texcoord2f[3] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationz);
#endif
- R_Mesh_State(&m);
- GL_ColorMask(0,0,0,1);
- GL_BlendFunc(GL_ONE, GL_ZERO);
- 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);
+ R_Mesh_State(&m);
+ GL_ColorMask(0,0,0,1);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ 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);
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex[0] = R_GetTexture(basetexture);
- m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
- m.texmatrix[0] = texture->currenttexmatrix;
- if (r_shadow_rtlight->currentcubemap != r_texture_whitecube)
- {
- m.texcubemap[1] = R_GetTexture(r_shadow_rtlight->currentcubemap);
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex[0] = R_GetTexture(basetexture);
+ m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
+ m.texmatrix[0] = texture->currenttexmatrix;
+ if (r_shadow_rtlight->currentcubemap != r_texture_whitecube)
+ {
+ m.texcubemap[1] = R_GetTexture(r_shadow_rtlight->currentcubemap);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[1] = rsurface_vertex3f;
- m.texmatrix[1] = r_shadow_entitytolight;
+ m.pointer_texcoord3f[1] = rsurface_vertex3f;
+ m.texmatrix[1] = r_shadow_entitytolight;
#else
- m.pointer_texcoord3f[1] = varray_texcoord3f[1];
- R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytolight);
+ m.pointer_texcoord3f[1] = varray_texcoord3f[1];
+ R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytolight);
#endif
- }
- GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
- }
- else
- {
- // 2/2/2 2D combine path (any dot3 card)
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex[0] = R_GetTexture(r_shadow_attenuation2dtexture);
+ }
+ GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
+ }
+ else
+ {
+ // 2/2/2 2D combine path (any dot3 card)
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex[0] = R_GetTexture(r_shadow_attenuation2dtexture);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[0] = rsurface_vertex3f;
- m.texmatrix[0] = r_shadow_entitytoattenuationxyz;
+ m.pointer_texcoord3f[0] = rsurface_vertex3f;
+ m.texmatrix[0] = r_shadow_entitytoattenuationxyz;
#else
- m.pointer_texcoord[0] = varray_texcoord2f[0];
- R_Shadow_Transform_Vertex3f_Texcoord2f(varray_texcoord2f[0] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
+ m.pointer_texcoord[0] = varray_texcoord2f[0];
+ R_Shadow_Transform_Vertex3f_Texcoord2f(varray_texcoord2f[0] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
#endif
- m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture);
+ m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[1] = rsurface_vertex3f;
- m.texmatrix[1] = r_shadow_entitytoattenuationz;
+ m.pointer_texcoord3f[1] = rsurface_vertex3f;
+ m.texmatrix[1] = r_shadow_entitytoattenuationz;
#else
- m.pointer_texcoord[1] = varray_texcoord2f[1];
- R_Shadow_Transform_Vertex3f_Texcoord2f(varray_texcoord2f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationz);
+ m.pointer_texcoord[1] = varray_texcoord2f[1];
+ R_Shadow_Transform_Vertex3f_Texcoord2f(varray_texcoord2f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationz);
#endif
- R_Mesh_State(&m);
- GL_ColorMask(0,0,0,1);
- GL_BlendFunc(GL_ONE, GL_ZERO);
- 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);
+ R_Mesh_State(&m);
+ GL_ColorMask(0,0,0,1);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ 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);
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex[0] = R_GetTexture(normalmaptexture);
- m.texcombinergb[0] = GL_REPLACE;
- m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
- m.texmatrix[0] = texture->currenttexmatrix;
- m.texcubemap[1] = R_GetTexture(r_texture_normalizationcube);
- m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
- m.pointer_texcoord3f[1] = varray_texcoord3f[1];
- R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, rsurface_svector3f + 3 * surface->num_firstvertex, rsurface_tvector3f + 3 * surface->num_firstvertex, rsurface_normal3f + 3 * surface->num_firstvertex, r_shadow_entitylightorigin);
- R_Mesh_State(&m);
- GL_BlendFunc(GL_DST_ALPHA, GL_ZERO);
- 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);
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex[0] = R_GetTexture(normalmaptexture);
+ m.texcombinergb[0] = GL_REPLACE;
+ m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
+ m.texmatrix[0] = texture->currenttexmatrix;
+ m.texcubemap[1] = R_GetTexture(r_texture_normalizationcube);
+ m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
+ m.pointer_texcoord3f[1] = varray_texcoord3f[1];
+ R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, rsurface_svector3f + 3 * surface->num_firstvertex, rsurface_tvector3f + 3 * surface->num_firstvertex, rsurface_normal3f + 3 * surface->num_firstvertex, r_shadow_entitylightorigin);
+ R_Mesh_State(&m);
+ GL_BlendFunc(GL_DST_ALPHA, GL_ZERO);
+ 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);
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex[0] = R_GetTexture(basetexture);
- m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
- m.texmatrix[0] = texture->currenttexmatrix;
- if (r_shadow_rtlight->currentcubemap != r_texture_whitecube)
- {
- m.texcubemap[1] = R_GetTexture(r_shadow_rtlight->currentcubemap);
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex[0] = R_GetTexture(basetexture);
+ m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
+ m.texmatrix[0] = texture->currenttexmatrix;
+ if (r_shadow_rtlight->currentcubemap != r_texture_whitecube)
+ {
+ m.texcubemap[1] = R_GetTexture(r_shadow_rtlight->currentcubemap);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[1] = rsurface_vertex3f;
- m.texmatrix[1] = r_shadow_entitytolight;
+ m.pointer_texcoord3f[1] = rsurface_vertex3f;
+ m.texmatrix[1] = r_shadow_entitytolight;
#else
- m.pointer_texcoord3f[1] = varray_texcoord3f[1];
- R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytolight);
+ m.pointer_texcoord3f[1] = varray_texcoord3f[1];
+ R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytolight);
#endif
- }
- GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
- }
- // this final code is shared
- 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);
}
- if (dospecular)
- {
- // FIXME: detect blendsquare!
- //if (gl_support_blendsquare)
- {
- colorscale = specularscale;
- GL_Color(1,1,1,1);
- if (r_shadow_texture3d.integer && r_textureunits.integer >= 2 && r_shadow_rtlight->currentcubemap != r_texture_whitecube /* && gl_support_blendsquare*/) // FIXME: detect blendsquare!
- {
- // 2/0/0/1/2 3D combine blendsquare path
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex[0] = R_GetTexture(normalmaptexture);
- m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
- m.texmatrix[0] = texture->currenttexmatrix;
- m.texcubemap[1] = R_GetTexture(r_texture_normalizationcube);
- m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
- m.pointer_texcoord3f[1] = varray_texcoord3f[1];
- R_Shadow_GenTexCoords_Specular_NormalCubeMap(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, rsurface_svector3f + 3 * surface->num_firstvertex, rsurface_tvector3f + 3 * surface->num_firstvertex, rsurface_normal3f + 3 * surface->num_firstvertex, r_shadow_entitylightorigin, r_shadow_entityeyeorigin);
- R_Mesh_State(&m);
- GL_ColorMask(0,0,0,1);
- // this squares the result
- GL_BlendFunc(GL_SRC_ALPHA, GL_ZERO);
- 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);
-
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- R_Mesh_State(&m);
- GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
- // square alpha in framebuffer a few times to make it shiny
- GL_BlendFunc(GL_ZERO, GL_DST_ALPHA);
- // these comments are a test run through this math for intensity 0.5
- // 0.5 * 0.5 = 0.25 (done by the BlendFunc earlier)
- // 0.25 * 0.25 = 0.0625 (this is another pass)
- // 0.0625 * 0.0625 = 0.00390625 (this is another pass)
- R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, elements);
- R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, elements);
- GL_LockArrays(0, 0);
-
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex3d[0] = R_GetTexture(r_shadow_attenuation3dtexture);
+ GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
+ }
+ // this final code is shared
+ 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_SpecularPass(const entity_render_t *ent, const texture_t *texture, const msurface_t *surface, const vec3_t lightcolorbase, rtexture_t *glosstexture, rtexture_t *normalmaptexture, float colorscale)
+{
+ int renders;
+ float color2[3];
+ rmeshstate_t m;
+ const int *elements = surface->groupmesh->data_element3i + surface->num_firsttriangle * 3;
+ // FIXME: detect blendsquare!
+ //if (!gl_support_blendsquare)
+ // return;
+ GL_Color(1,1,1,1);
+ if (r_shadow_texture3d.integer && r_textureunits.integer >= 2 && r_shadow_rtlight->currentcubemap != r_texture_whitecube /* && gl_support_blendsquare*/) // FIXME: detect blendsquare!
+ {
+ // 2/0/0/1/2 3D combine blendsquare path
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex[0] = R_GetTexture(normalmaptexture);
+ m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
+ m.texmatrix[0] = texture->currenttexmatrix;
+ m.texcubemap[1] = R_GetTexture(r_texture_normalizationcube);
+ m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
+ m.pointer_texcoord3f[1] = varray_texcoord3f[1];
+ R_Shadow_GenTexCoords_Specular_NormalCubeMap(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, rsurface_svector3f + 3 * surface->num_firstvertex, rsurface_tvector3f + 3 * surface->num_firstvertex, rsurface_normal3f + 3 * surface->num_firstvertex, r_shadow_entitylightorigin, r_shadow_entityeyeorigin);
+ R_Mesh_State(&m);
+ GL_ColorMask(0,0,0,1);
+ // this squares the result
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ZERO);
+ 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);
+
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ R_Mesh_State(&m);
+ GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
+ // square alpha in framebuffer a few times to make it shiny
+ GL_BlendFunc(GL_ZERO, GL_DST_ALPHA);
+ // these comments are a test run through this math for intensity 0.5
+ // 0.5 * 0.5 = 0.25 (done by the BlendFunc earlier)
+ // 0.25 * 0.25 = 0.0625 (this is another pass)
+ // 0.0625 * 0.0625 = 0.00390625 (this is another pass)
+ R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, elements);
+ R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, elements);
+ GL_LockArrays(0, 0);
+
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex3d[0] = R_GetTexture(r_shadow_attenuation3dtexture);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[0] = rsurface_vertex3f;
- m.texmatrix[0] = r_shadow_entitytoattenuationxyz;
+ m.pointer_texcoord3f[0] = rsurface_vertex3f;
+ m.texmatrix[0] = r_shadow_entitytoattenuationxyz;
#else
- m.pointer_texcoord3f[0] = varray_texcoord3f[0];
- R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[0] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
+ m.pointer_texcoord3f[0] = varray_texcoord3f[0];
+ R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[0] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
#endif
- R_Mesh_State(&m);
- GL_BlendFunc(GL_DST_ALPHA, GL_ZERO);
- 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);
-
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex[0] = R_GetTexture(glosstexture);
- m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
- m.texmatrix[0] = texture->currenttexmatrix;
- if (r_shadow_rtlight->currentcubemap != r_texture_whitecube)
- {
- m.texcubemap[1] = R_GetTexture(r_shadow_rtlight->currentcubemap);
+ R_Mesh_State(&m);
+ GL_BlendFunc(GL_DST_ALPHA, GL_ZERO);
+ 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);
+
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex[0] = R_GetTexture(glosstexture);
+ m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
+ m.texmatrix[0] = texture->currenttexmatrix;
+ if (r_shadow_rtlight->currentcubemap != r_texture_whitecube)
+ {
+ m.texcubemap[1] = R_GetTexture(r_shadow_rtlight->currentcubemap);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[1] = rsurface_vertex3f;
- m.texmatrix[1] = r_shadow_entitytolight;
+ m.pointer_texcoord3f[1] = rsurface_vertex3f;
+ m.texmatrix[1] = r_shadow_entitytolight;
#else
- m.pointer_texcoord3f[1] = varray_texcoord3f[1];
- R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytolight);
+ m.pointer_texcoord3f[1] = varray_texcoord3f[1];
+ R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytolight);
#endif
- }
- GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
- }
- else if (r_shadow_texture3d.integer && r_textureunits.integer >= 2 && r_shadow_rtlight->currentcubemap == r_texture_whitecube /* && gl_support_blendsquare*/) // FIXME: detect blendsquare!
- {
- // 2/0/0/2 3D combine blendsquare path
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex[0] = R_GetTexture(normalmaptexture);
- m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
- m.texmatrix[0] = texture->currenttexmatrix;
- m.texcubemap[1] = R_GetTexture(r_texture_normalizationcube);
- m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
- m.pointer_texcoord3f[1] = varray_texcoord3f[1];
- R_Shadow_GenTexCoords_Specular_NormalCubeMap(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, rsurface_svector3f + 3 * surface->num_firstvertex, rsurface_tvector3f + 3 * surface->num_firstvertex, rsurface_normal3f + 3 * surface->num_firstvertex, r_shadow_entitylightorigin, r_shadow_entityeyeorigin);
- R_Mesh_State(&m);
- GL_ColorMask(0,0,0,1);
- // this squares the result
- GL_BlendFunc(GL_SRC_ALPHA, GL_ZERO);
- 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);
-
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- R_Mesh_State(&m);
- GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
- // square alpha in framebuffer a few times to make it shiny
- GL_BlendFunc(GL_ZERO, GL_DST_ALPHA);
- // these comments are a test run through this math for intensity 0.5
- // 0.5 * 0.5 = 0.25 (done by the BlendFunc earlier)
- // 0.25 * 0.25 = 0.0625 (this is another pass)
- // 0.0625 * 0.0625 = 0.00390625 (this is another pass)
- R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, elements);
- R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, elements);
- GL_LockArrays(0, 0);
-
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex[0] = R_GetTexture(glosstexture);
- m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
- m.texmatrix[0] = texture->currenttexmatrix;
- m.tex3d[1] = R_GetTexture(r_shadow_attenuation3dtexture);
+ }
+ GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
+ }
+ else if (r_shadow_texture3d.integer && r_textureunits.integer >= 2 && r_shadow_rtlight->currentcubemap == r_texture_whitecube /* && gl_support_blendsquare*/) // FIXME: detect blendsquare!
+ {
+ // 2/0/0/2 3D combine blendsquare path
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex[0] = R_GetTexture(normalmaptexture);
+ m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
+ m.texmatrix[0] = texture->currenttexmatrix;
+ m.texcubemap[1] = R_GetTexture(r_texture_normalizationcube);
+ m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
+ m.pointer_texcoord3f[1] = varray_texcoord3f[1];
+ R_Shadow_GenTexCoords_Specular_NormalCubeMap(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, rsurface_svector3f + 3 * surface->num_firstvertex, rsurface_tvector3f + 3 * surface->num_firstvertex, rsurface_normal3f + 3 * surface->num_firstvertex, r_shadow_entitylightorigin, r_shadow_entityeyeorigin);
+ R_Mesh_State(&m);
+ GL_ColorMask(0,0,0,1);
+ // this squares the result
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ZERO);
+ 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);
+
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ R_Mesh_State(&m);
+ GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
+ // square alpha in framebuffer a few times to make it shiny
+ GL_BlendFunc(GL_ZERO, GL_DST_ALPHA);
+ // these comments are a test run through this math for intensity 0.5
+ // 0.5 * 0.5 = 0.25 (done by the BlendFunc earlier)
+ // 0.25 * 0.25 = 0.0625 (this is another pass)
+ // 0.0625 * 0.0625 = 0.00390625 (this is another pass)
+ R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, elements);
+ R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, elements);
+ GL_LockArrays(0, 0);
+
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex[0] = R_GetTexture(glosstexture);
+ m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
+ m.texmatrix[0] = texture->currenttexmatrix;
+ m.tex3d[1] = R_GetTexture(r_shadow_attenuation3dtexture);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[1] = rsurface_vertex3f;
- m.texmatrix[1] = r_shadow_entitytoattenuationxyz;
+ m.pointer_texcoord3f[1] = rsurface_vertex3f;
+ m.texmatrix[1] = r_shadow_entitytoattenuationxyz;
#else
- m.pointer_texcoord3f[1] = varray_texcoord3f[1];
- R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
+ m.pointer_texcoord3f[1] = varray_texcoord3f[1];
+ R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
#endif
- GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
- }
- else
- {
- // 2/0/0/2/2 2D combine blendsquare path
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex[0] = R_GetTexture(normalmaptexture);
- m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
- m.texmatrix[0] = texture->currenttexmatrix;
- m.texcubemap[1] = R_GetTexture(r_texture_normalizationcube);
- m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
- m.pointer_texcoord3f[1] = varray_texcoord3f[1];
- R_Shadow_GenTexCoords_Specular_NormalCubeMap(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, rsurface_svector3f + 3 * surface->num_firstvertex, rsurface_tvector3f + 3 * surface->num_firstvertex, rsurface_normal3f + 3 * surface->num_firstvertex, r_shadow_entitylightorigin, r_shadow_entityeyeorigin);
- R_Mesh_State(&m);
- GL_ColorMask(0,0,0,1);
- // this squares the result
- GL_BlendFunc(GL_SRC_ALPHA, GL_ZERO);
- 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);
-
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- R_Mesh_State(&m);
- GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
- // square alpha in framebuffer a few times to make it shiny
- GL_BlendFunc(GL_ZERO, GL_DST_ALPHA);
- // these comments are a test run through this math for intensity 0.5
- // 0.5 * 0.5 = 0.25 (done by the BlendFunc earlier)
- // 0.25 * 0.25 = 0.0625 (this is another pass)
- // 0.0625 * 0.0625 = 0.00390625 (this is another pass)
- R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, elements);
- R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, elements);
- GL_LockArrays(0, 0);
-
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex[0] = R_GetTexture(r_shadow_attenuation2dtexture);
+ GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
+ }
+ else
+ {
+ // 2/0/0/2/2 2D combine blendsquare path
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex[0] = R_GetTexture(normalmaptexture);
+ m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
+ m.texmatrix[0] = texture->currenttexmatrix;
+ m.texcubemap[1] = R_GetTexture(r_texture_normalizationcube);
+ m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
+ m.pointer_texcoord3f[1] = varray_texcoord3f[1];
+ R_Shadow_GenTexCoords_Specular_NormalCubeMap(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, rsurface_svector3f + 3 * surface->num_firstvertex, rsurface_tvector3f + 3 * surface->num_firstvertex, rsurface_normal3f + 3 * surface->num_firstvertex, r_shadow_entitylightorigin, r_shadow_entityeyeorigin);
+ R_Mesh_State(&m);
+ GL_ColorMask(0,0,0,1);
+ // this squares the result
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ZERO);
+ 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);
+
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ R_Mesh_State(&m);
+ GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
+ // square alpha in framebuffer a few times to make it shiny
+ GL_BlendFunc(GL_ZERO, GL_DST_ALPHA);
+ // these comments are a test run through this math for intensity 0.5
+ // 0.5 * 0.5 = 0.25 (done by the BlendFunc earlier)
+ // 0.25 * 0.25 = 0.0625 (this is another pass)
+ // 0.0625 * 0.0625 = 0.00390625 (this is another pass)
+ R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, elements);
+ R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, elements);
+ GL_LockArrays(0, 0);
+
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex[0] = R_GetTexture(r_shadow_attenuation2dtexture);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[0] = rsurface_vertex3f;
- m.texmatrix[0] = r_shadow_entitytoattenuationxyz;
+ m.pointer_texcoord3f[0] = rsurface_vertex3f;
+ m.texmatrix[0] = r_shadow_entitytoattenuationxyz;
#else
- m.pointer_texcoord[0] = varray_texcoord2f[0];
- R_Shadow_Transform_Vertex3f_Texcoord2f(varray_texcoord2f[0] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
+ m.pointer_texcoord[0] = varray_texcoord2f[0];
+ R_Shadow_Transform_Vertex3f_Texcoord2f(varray_texcoord2f[0] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationxyz);
#endif
- m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture);
+ m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[1] = rsurface_vertex3f;
- m.texmatrix[1] = r_shadow_entitytoattenuationz;
+ m.pointer_texcoord3f[1] = rsurface_vertex3f;
+ m.texmatrix[1] = r_shadow_entitytoattenuationz;
#else
- m.pointer_texcoord[1] = varray_texcoord2f[1];
- R_Shadow_Transform_Vertex3f_Texcoord2f(varray_texcoord2f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationz);
+ m.pointer_texcoord[1] = varray_texcoord2f[1];
+ R_Shadow_Transform_Vertex3f_Texcoord2f(varray_texcoord2f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytoattenuationz);
#endif
- R_Mesh_State(&m);
- GL_BlendFunc(GL_DST_ALPHA, GL_ZERO);
- 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);
-
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = rsurface_vertex3f;
- m.tex[0] = R_GetTexture(glosstexture);
- m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
- m.texmatrix[0] = texture->currenttexmatrix;
- if (r_shadow_rtlight->currentcubemap != r_texture_whitecube)
- {
- m.texcubemap[1] = R_GetTexture(r_shadow_rtlight->currentcubemap);
+ R_Mesh_State(&m);
+ GL_BlendFunc(GL_DST_ALPHA, GL_ZERO);
+ 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);
+
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = rsurface_vertex3f;
+ m.tex[0] = R_GetTexture(glosstexture);
+ m.pointer_texcoord[0] = surface->groupmesh->data_texcoordtexture2f;
+ m.texmatrix[0] = texture->currenttexmatrix;
+ if (r_shadow_rtlight->currentcubemap != r_texture_whitecube)
+ {
+ m.texcubemap[1] = R_GetTexture(r_shadow_rtlight->currentcubemap);
#ifdef USETEXMATRIX
- m.pointer_texcoord3f[1] = rsurface_vertex3f;
- m.texmatrix[1] = r_shadow_entitytolight;
+ m.pointer_texcoord3f[1] = rsurface_vertex3f;
+ m.texmatrix[1] = r_shadow_entitytolight;
#else
- m.pointer_texcoord3f[1] = varray_texcoord3f[1];
- R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytolight);
+ m.pointer_texcoord3f[1] = varray_texcoord3f[1];
+ R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1] + 3 * surface->num_firstvertex, surface->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, &r_shadow_entitytolight);
#endif
- }
- 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_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);
- 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);
- }
+ 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)
+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;
- int renders;
- float ambientcolor2[3], diffusecolor2[3];
+ float ambientcolorbase[3], diffusecolorbase[3];
+ float ambientcolorpants[3], diffusecolorpants[3];
+ float ambientcolorshirt[3], diffusecolorshirt[3];
rmeshstate_t m;
- qboolean doambientbase = r_shadow_rtlight->ambientscale * VectorLength2(lightcolorbase) > 0.00001 && basetexture != r_texture_black;
- qboolean dodiffusebase = r_shadow_rtlight->diffusescale * VectorLength2(lightcolorbase) > 0.00001 && basetexture != r_texture_black;
- qboolean doambientpants = r_shadow_rtlight->ambientscale * VectorLength2(lightcolorpants) > 0.00001 && pantstexture != r_texture_black;
- qboolean dodiffusepants = r_shadow_rtlight->diffusescale * VectorLength2(lightcolorpants) > 0.00001 && pantstexture != r_texture_black;
- qboolean doambientshirt = r_shadow_rtlight->ambientscale * VectorLength2(lightcolorshirt) > 0.00001 && shirttexture != r_texture_black;
- qboolean dodiffuseshirt = r_shadow_rtlight->diffusescale * VectorLength2(lightcolorshirt) > 0.00001 && shirttexture != r_texture_black;
- //qboolean dospecular = specularscale * VectorLength2(lightcolorbase) > 0.00001 && glosstexture != r_texture_black;
- // TODO: add direct pants/shirt rendering
- if (doambientpants || dodiffusepants)
- R_Shadow_RenderSurfacesLighting_Light_Vertex(ent, texture, numsurfaces, surfacelist, lightcolorpants, vec3_origin, vec3_origin, pantstexture, r_texture_black, r_texture_black, normalmaptexture, r_texture_black, 0);
- if (doambientshirt || dodiffuseshirt)
- R_Shadow_RenderSurfacesLighting_Light_Vertex(ent, texture, numsurfaces, surfacelist, lightcolorshirt, vec3_origin, vec3_origin, shirttexture, r_texture_black, r_texture_black, normalmaptexture, r_texture_black, 0);
- if (!doambientbase && !dodiffusebase)
- return;
- VectorScale(lightcolorbase, r_shadow_rtlight->ambientscale, ambientcolor2);
- VectorScale(lightcolorbase, r_shadow_rtlight->diffusescale, diffusecolor2);
- GL_BlendFunc(GL_ONE, GL_ONE);
+ 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)
for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++)
{
const msurface_t *surface = surfacelist[surfacelistindex];
- const int *elements = surface->groupmesh->data_element3i + surface->num_firsttriangle * 3;
RSurf_SetVertexPointer(ent, texture, surface, r_shadow_entityeyeorigin);
if (!rsurface_svector3f)
{
#endif
}
}
- R_Shadow_RenderSurfacesLighting_Light_Vertex_Shading(surface, diffusecolor2, ambientcolor2, 0);
- for (renders = 0;renders < 64 && (ambientcolor2[0] > renders || ambientcolor2[1] > renders || ambientcolor2[2] > renders || diffusecolor2[0] > renders || diffusecolor2[1] > renders || diffusecolor2[2] > renders);renders++)
+ R_Mesh_TexBind(0, R_GetTexture(basetexture));
+ R_Shadow_RenderSurfacesLighting_Light_Vertex_Pass(surface, diffusecolorbase, ambientcolorbase);
+ if (dopants)
{
- 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);
- }
+ R_Mesh_TexBind(0, R_GetTexture(pantstexture));
+ R_Shadow_RenderSurfacesLighting_Light_Vertex_Pass(surface, diffusecolorpants, ambientcolorpants);
+ }
+ if (doshirt)
+ {
+ R_Mesh_TexBind(0, R_GetTexture(shirttexture));
+ R_Shadow_RenderSurfacesLighting_Light_Vertex_Pass(surface, diffusecolorshirt, ambientcolorshirt);
}
}
}
// FIXME: support MATERIALFLAG_NODEPTHTEST
vec3_t lightcolorbase, lightcolorpants, lightcolorshirt;
rtexture_t *basetexture;
+ rtexture_t *pantstexture;
+ rtexture_t *shirttexture;
rtexture_t *glosstexture;
float specularscale;
- if ((texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (ent->flags & RENDER_NOCULLFACE))
- qglDisable(GL_CULL_FACE);
- else
- qglEnable(GL_CULL_FACE);
+ qboolean dopants, doshirt;
glosstexture = r_texture_black;
- specularscale = 0;
if (r_shadow_gloss.integer > 0)
{
if (texture->skin.gloss)
lightcolorbase[0] = r_shadow_rtlight->currentcolor[0] * ent->colormod[0] * texture->currentalpha;
lightcolorbase[1] = r_shadow_rtlight->currentcolor[1] * ent->colormod[1] * texture->currentalpha;
lightcolorbase[2] = r_shadow_rtlight->currentcolor[2] * ent->colormod[2] * texture->currentalpha;
- lightcolorpants[0] = r_shadow_rtlight->currentcolor[0] * ent->colormap_pantscolor[0] * texture->currentalpha;
- lightcolorpants[1] = r_shadow_rtlight->currentcolor[1] * ent->colormap_pantscolor[1] * texture->currentalpha;
- lightcolorpants[2] = r_shadow_rtlight->currentcolor[2] * ent->colormap_pantscolor[2] * texture->currentalpha;
- lightcolorshirt[0] = r_shadow_rtlight->currentcolor[0] * ent->colormap_shirtcolor[0] * texture->currentalpha;
- lightcolorshirt[1] = r_shadow_rtlight->currentcolor[1] * ent->colormap_shirtcolor[1] * texture->currentalpha;
- lightcolorshirt[2] = r_shadow_rtlight->currentcolor[2] * ent->colormap_shirtcolor[2] * texture->currentalpha;
- if (ent->colormap >= 0)
- {
- basetexture = texture->skin.base;
- if ((r_shadow_rtlight->ambientscale + r_shadow_rtlight->diffusescale) * (VectorLength2(lightcolorbase) + VectorLength2(lightcolorpants) + VectorLength2(lightcolorshirt)) + specularscale * VectorLength2(lightcolorbase) < (1.0f / 1048576.0f))
- return;
- }
+ if ((r_shadow_rtlight->ambientscale + r_shadow_rtlight->diffusescale) * VectorLength2(lightcolorbase) + specularscale * VectorLength2(lightcolorbase) < (1.0f / 1048576.0f))
+ return;
+ if ((texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (ent->flags & RENDER_NOCULLFACE))
+ qglDisable(GL_CULL_FACE);
else
+ qglEnable(GL_CULL_FACE);
+ dopants = texture->skin.pants != NULL && VectorLength2(ent->colormap_pantscolor) >= (1.0f / 1048576.0f);
+ doshirt = texture->skin.shirt != NULL && VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f);
+ if (dopants + doshirt)
{
- basetexture = texture->skin.merged ? texture->skin.merged : texture->skin.base;
- if ((r_shadow_rtlight->ambientscale + r_shadow_rtlight->diffusescale) * VectorLength2(lightcolorbase) + specularscale * VectorLength2(lightcolorbase) < (1.0f / 1048576.0f))
- return;
+ if (dopants)
+ {
+ lightcolorpants[0] = lightcolorbase[0] * ent->colormap_pantscolor[0];
+ lightcolorpants[1] = lightcolorbase[1] * ent->colormap_pantscolor[1];
+ lightcolorpants[2] = lightcolorbase[2] * ent->colormap_pantscolor[2];
+ }
+ else
+ {
+ pantstexture = r_texture_black;
+ VectorClear(lightcolorpants);
+ }
+ if (doshirt)
+ {
+ shirttexture = texture->skin.shirt;
+ lightcolorshirt[0] = lightcolorbase[0] * ent->colormap_shirtcolor[0];
+ lightcolorshirt[1] = lightcolorbase[1] * ent->colormap_shirtcolor[1];
+ lightcolorshirt[2] = lightcolorbase[2] * ent->colormap_shirtcolor[2];
+ }
+ else
+ {
+ shirttexture = r_texture_black;
+ VectorClear(lightcolorshirt);
+ }
+ switch (r_shadow_rendermode)
+ {
+ case R_SHADOW_RENDERMODE_VISIBLELIGHTING:
+ R_Shadow_RenderSurfacesLighting_VisibleLighting(ent, texture, numsurfaces, surfacelist, lightcolorbase, lightcolorpants, lightcolorshirt, texture->skin.base, texture->skin.pants, texture->skin.shirt, texture->skin.nmap, glosstexture, specularscale, dopants, doshirt);
+ break;
+ case R_SHADOW_RENDERMODE_LIGHT_GLSL:
+ R_Shadow_RenderSurfacesLighting_Light_GLSL(ent, texture, numsurfaces, surfacelist, lightcolorbase, lightcolorpants, lightcolorshirt, texture->skin.base, texture->skin.pants, texture->skin.shirt, texture->skin.nmap, glosstexture, specularscale, dopants, doshirt);
+ break;
+ case R_SHADOW_RENDERMODE_LIGHT_DOT3:
+ R_Shadow_RenderSurfacesLighting_Light_Dot3(ent, texture, numsurfaces, surfacelist, lightcolorbase, lightcolorpants, lightcolorshirt, texture->skin.base, texture->skin.pants, texture->skin.shirt, texture->skin.nmap, glosstexture, specularscale, dopants, doshirt);
+ break;
+ case R_SHADOW_RENDERMODE_LIGHT_VERTEX:
+ R_Shadow_RenderSurfacesLighting_Light_Vertex(ent, texture, numsurfaces, surfacelist, lightcolorbase, lightcolorpants, lightcolorshirt, texture->skin.base, texture->skin.pants, texture->skin.shirt, texture->skin.nmap, glosstexture, specularscale, dopants, doshirt);
+ break;
+ default:
+ Con_Printf("R_Shadow_RenderSurfacesLighting: unknown r_shadow_rendermode %i\n", r_shadow_rendermode);
+ break;
+ }
}
- switch (r_shadow_rendermode)
+ else
{
- case R_SHADOW_RENDERMODE_VISIBLELIGHTING:
- R_Shadow_RenderSurfacesLighting_VisibleLighting(ent, texture, numsurfaces, surfacelist, lightcolorbase, lightcolorpants, lightcolorshirt, basetexture, texture->skin.pants, texture->skin.shirt, texture->skin.nmap, glosstexture, specularscale);
- break;
- case R_SHADOW_RENDERMODE_LIGHT_GLSL:
- R_Shadow_RenderSurfacesLighting_Light_GLSL(ent, texture, numsurfaces, surfacelist, lightcolorbase, lightcolorpants, lightcolorshirt, basetexture, texture->skin.pants, texture->skin.shirt, texture->skin.nmap, glosstexture, specularscale);
- break;
- case R_SHADOW_RENDERMODE_LIGHT_DOT3:
- R_Shadow_RenderSurfacesLighting_Light_Dot3(ent, texture, numsurfaces, surfacelist, lightcolorbase, lightcolorpants, lightcolorshirt, basetexture, texture->skin.pants, texture->skin.shirt, texture->skin.nmap, glosstexture, specularscale);
- break;
- case R_SHADOW_RENDERMODE_LIGHT_VERTEX:
- R_Shadow_RenderSurfacesLighting_Light_Vertex(ent, texture, numsurfaces, surfacelist, lightcolorbase, lightcolorpants, lightcolorshirt, basetexture, texture->skin.pants, texture->skin.shirt, texture->skin.nmap, glosstexture, specularscale);
- break;
- default:
- Con_Printf("R_Shadow_RenderSurfacesLighting: unknown r_shadow_rendermode %i\n", r_shadow_rendermode);
- break;
+ basetexture = texture->skin.merged ? texture->skin.merged : texture->skin.base;
+ switch (r_shadow_rendermode)
+ {
+ case R_SHADOW_RENDERMODE_VISIBLELIGHTING:
+ R_Shadow_RenderSurfacesLighting_VisibleLighting(ent, texture, numsurfaces, surfacelist, lightcolorbase, vec3_origin, vec3_origin, basetexture, r_texture_black, r_texture_black, texture->skin.nmap, glosstexture, specularscale, false, false);
+ break;
+ case R_SHADOW_RENDERMODE_LIGHT_GLSL:
+ R_Shadow_RenderSurfacesLighting_Light_GLSL(ent, texture, numsurfaces, surfacelist, lightcolorbase, vec3_origin, vec3_origin, basetexture, r_texture_black, r_texture_black, texture->skin.nmap, glosstexture, specularscale, false, false);
+ break;
+ case R_SHADOW_RENDERMODE_LIGHT_DOT3:
+ R_Shadow_RenderSurfacesLighting_Light_Dot3(ent, texture, numsurfaces, surfacelist, lightcolorbase, vec3_origin, vec3_origin, basetexture, r_texture_black, r_texture_black, texture->skin.nmap, glosstexture, specularscale, false, false);
+ break;
+ case R_SHADOW_RENDERMODE_LIGHT_VERTEX:
+ R_Shadow_RenderSurfacesLighting_Light_Vertex(ent, texture, numsurfaces, surfacelist, lightcolorbase, vec3_origin, vec3_origin, basetexture, r_texture_black, r_texture_black, texture->skin.nmap, glosstexture, specularscale, false, false);
+ break;
+ default:
+ Con_Printf("R_Shadow_RenderSurfacesLighting: unknown r_shadow_rendermode %i\n", r_shadow_rendermode);
+ break;
+ }
}
}
Matrix4x4_Transform(&ent->inversematrix, r_shadow_rtlight->shadoworigin, r_shadow_entitylightorigin);
Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, r_shadow_entityeyeorigin);
R_Mesh_Matrix(&ent->matrix);
- if (r_shadow_rendermode == R_SHADOW_RENDERMODE_LIGHT_GLSL)
- {
- R_Mesh_TexMatrix(3, &r_shadow_entitytolight);
- qglUniform3fARB(qglGetUniformLocationARB(r_shadow_lightprog, "LightPosition"), r_shadow_entitylightorigin[0], r_shadow_entitylightorigin[1], r_shadow_entitylightorigin[2]);CHECKGLERROR
- if (r_shadow_lightpermutation & (SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_FOG | SHADERPERMUTATION_OFFSETMAPPING))
- {
- qglUniform3fARB(qglGetUniformLocationARB(r_shadow_lightprog, "EyePosition"), r_shadow_entityeyeorigin[0], r_shadow_entityeyeorigin[1], r_shadow_entityeyeorigin[2]);CHECKGLERROR
- }
- }
}
void R_Shadow_DrawEntityLight(entity_render_t *ent, int numsurfaces, int *surfacelist)