- GL_UseColorArray();
- memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4]));
- VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color);
- R_Shadow_VertexLighting(varray_color, numverts, varray_vertex, normals, color, relativelightorigin, lightradius);
- R_Mesh_Draw(numverts, numtriangles, elements);
- }
- }
-}
-
-void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elements, const float *svectors, const float *tvectors, const float *normals, const float *texcoords, const float *relativelightorigin, const float *relativeeyeorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *glosstexture, rtexture_t *bumptexture, rtexture_t *lightcubemap)
-{
- int renders;
- float color[3];
- rmeshstate_t m;
- if (!gl_dot3arb)
- return;
- memset(&m, 0, sizeof(m));
- if (!bumptexture)
- bumptexture = r_shadow_blankbumptexture;
- if (!glosstexture)
- glosstexture = r_shadow_blankglosstexture;
- if (r_shadow_gloss.integer >= 2 || (r_shadow_gloss.integer >= 1 && glosstexture != r_shadow_blankglosstexture))
- {
- if (r_shadow_texture3d.integer && r_textureunits.integer >= 2 && lightcubemap /*&& gl_support_blendsquare*/) // FIXME: detect blendsquare!
- {
- // 2/0/0/0/1/2 3D combine blendsquare path
- m.tex[0] = R_GetTexture(bumptexture);
- m.texcubemap[1] = R_GetTexture(r_shadow_normalscubetexture);
- m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
- R_Mesh_TextureState(&m);
- qglColorMask(0,0,0,1);
- qglDisable(GL_BLEND);
- GL_Color(1,1,1,1);
- memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4]));
- R_Shadow_GenTexCoords_Specular_NormalCubeMap(varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin, relativeeyeorigin);
- R_Mesh_Draw(numverts, numtriangles, elements);
- c_rt_lightmeshes++;
- c_rt_lighttris += numtriangles;
-
- m.tex[0] = 0;
- m.texcubemap[1] = 0;
- m.texcombinergb[1] = GL_MODULATE;
- R_Mesh_TextureState(&m);
- // square alpha in framebuffer a few times to make it shiny
- qglBlendFunc(GL_ZERO, GL_DST_ALPHA);
- qglEnable(GL_BLEND);
- // these comments are a test run through this math for intensity 0.5
- // 0.5 * 0.5 = 0.25
- R_Mesh_Draw(numverts, numtriangles, elements);
- c_rt_lightmeshes++;
- c_rt_lighttris += numtriangles;
- // 0.25 * 0.25 = 0.0625
- R_Mesh_Draw(numverts, numtriangles, elements);
- c_rt_lightmeshes++;
- c_rt_lighttris += numtriangles;
- // 0.0625 * 0.0625 = 0.00390625
- R_Mesh_Draw(numverts, numtriangles, elements);
- c_rt_lightmeshes++;
- c_rt_lighttris += numtriangles;
-
- m.tex3d[0] = R_GetTexture(r_shadow_attenuation3dtexture);
- R_Mesh_TextureState(&m);
- qglBlendFunc(GL_DST_ALPHA, GL_ZERO);
- R_Shadow_TransformVertices(varray_texcoord[0], numverts, varray_vertex, matrix_modeltoattenuationxyz);
- R_Mesh_Draw(numverts, numtriangles, elements);
- c_rt_lightmeshes++;
- c_rt_lighttris += numtriangles;
-
- m.tex3d[0] = 0;
- m.tex[0] = R_GetTexture(glosstexture);
- m.texcubemap[1] = R_GetTexture(lightcubemap);
- R_Mesh_TextureState(&m);
- qglColorMask(1,1,1,0);
- qglBlendFunc(GL_DST_ALPHA, GL_ONE);
- memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4]));
- if (lightcubemap)
- R_Shadow_TransformVertices(varray_texcoord[1], numverts, varray_vertex, matrix_modeltofilter);
-
- VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value * 0.25f, color);
- for (renders = 0;renders < 64 && (color[0] > 0 || color[1] > 0 || color[2] > 0);renders++, color[0] = max(0, color[0] - 1.0f), color[1] = max(0, color[1] - 1.0f), color[2] = max(0, color[2] - 1.0f))
+ }
+ }
+ else if (r_shadow_texture3d.integer && r_textureunits.integer >= 2 && !lightcubemap /*&& gl_support_blendsquare*/) // FIXME: detect blendsquare!
+ {
+ // 2/0/0/2 3D combine blendsquare path
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = vertex3f;
+ m.tex[0] = R_GetTexture(bumptexture);
+ m.pointer_texcoord[0] = texcoord2f;
+ m.texcubemap[1] = R_GetTexture(r_shadow_normalcubetexture);
+ m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
+ m.pointer_texcoord3f[1] = varray_texcoord3f[1];
+ R_Shadow_GenTexCoords_Specular_NormalCubeMap(varray_texcoord3f[1], numverts, vertex3f, svector3f, tvector3f, normal3f, relativelightorigin, relativeeyeorigin);
+ R_Mesh_State(&m);
+ GL_ColorMask(0,0,0,1);
+ // this squares the result
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ZERO);
+ GL_LockArrays(0, numverts);
+ R_Mesh_Draw(numverts, numtriangles, elements);
+ GL_LockArrays(0, 0);
+ c_rt_lightmeshes++;
+ c_rt_lighttris += numtriangles;
+
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = vertex3f;
+ R_Mesh_State(&m);
+ GL_LockArrays(0, numverts);
+ // 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(numverts, numtriangles, elements);
+ c_rt_lightmeshes++;
+ c_rt_lighttris += numtriangles;
+ R_Mesh_Draw(numverts, numtriangles, elements);
+ c_rt_lightmeshes++;
+ c_rt_lighttris += numtriangles;
+ GL_LockArrays(0, 0);
+
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = vertex3f;
+ m.tex[0] = R_GetTexture(glosstexture);
+ m.pointer_texcoord[0] = texcoord2f;
+ m.tex3d[1] = R_GetTexture(r_shadow_attenuation3dtexture);
+#if USETEXMATRIX
+ m.pointer_texcoord3f[1] = vertex3f;
+ m.texmatrix[1] = *matrix_modeltoattenuationxyz;
+#else
+ m.pointer_texcoord3f[1] = varray_texcoord3f[1];
+ R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltoattenuationxyz);
+#endif
+ }
+ else
+ {
+ // 2/0/0/2/2 2D combine blendsquare path
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = vertex3f;
+ m.tex[0] = R_GetTexture(bumptexture);
+ m.pointer_texcoord[0] = texcoord2f;
+ m.texcubemap[1] = R_GetTexture(r_shadow_normalcubetexture);
+ m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
+ m.pointer_texcoord3f[1] = varray_texcoord3f[1];
+ R_Shadow_GenTexCoords_Specular_NormalCubeMap(varray_texcoord3f[1], numverts, vertex3f, svector3f, tvector3f, normal3f, relativelightorigin, relativeeyeorigin);
+ R_Mesh_State(&m);
+ GL_ColorMask(0,0,0,1);
+ // this squares the result
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ZERO);
+ GL_LockArrays(0, numverts);
+ R_Mesh_Draw(numverts, numtriangles, elements);
+ GL_LockArrays(0, 0);
+ c_rt_lightmeshes++;
+ c_rt_lighttris += numtriangles;
+
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = vertex3f;
+ R_Mesh_State(&m);
+ GL_LockArrays(0, numverts);
+ // 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(numverts, numtriangles, elements);
+ c_rt_lightmeshes++;
+ c_rt_lighttris += numtriangles;
+ R_Mesh_Draw(numverts, numtriangles, elements);
+ c_rt_lightmeshes++;
+ c_rt_lighttris += numtriangles;
+ GL_LockArrays(0, 0);
+
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = vertex3f;
+ m.tex[0] = R_GetTexture(r_shadow_attenuation2dtexture);
+#if USETEXMATRIX
+ m.pointer_texcoord3f[0] = vertex3f;
+ m.texmatrix[0] = *matrix_modeltoattenuationxyz;
+#else
+ m.pointer_texcoord[0] = varray_texcoord2f[0];
+ R_Shadow_Transform_Vertex3f_TexCoord2f(varray_texcoord2f[0], numverts, vertex3f, matrix_modeltoattenuationxyz);
+#endif
+ m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture);
+#if USETEXMATRIX
+ m.pointer_texcoord3f[1] = vertex3f;
+ m.texmatrix[1] = *matrix_modeltoattenuationz;
+#else
+ m.pointer_texcoord[1] = varray_texcoord2f[1];
+ R_Shadow_Transform_Vertex3f_TexCoord2f(varray_texcoord2f[1], numverts, vertex3f, matrix_modeltoattenuationz);
+#endif
+ R_Mesh_State(&m);
+ GL_BlendFunc(GL_DST_ALPHA, GL_ZERO);
+ GL_LockArrays(0, numverts);
+ R_Mesh_Draw(numverts, numtriangles, elements);
+ GL_LockArrays(0, 0);
+ c_rt_lightmeshes++;
+ c_rt_lighttris += numtriangles;
+
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = vertex3f;
+ m.tex[0] = R_GetTexture(glosstexture);
+ m.pointer_texcoord[0] = texcoord2f;
+ if (lightcubemap)
+ {
+ m.texcubemap[1] = R_GetTexture(lightcubemap);
+#if USETEXMATRIX
+ m.pointer_texcoord3f[1] = vertex3f;
+ m.texmatrix[1] = *matrix_modeltolight;
+#else
+ m.pointer_texcoord3f[1] = varray_texcoord3f[1];
+ R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltolight);
+#endif
+ }
+ }
+ }
+ R_Mesh_State(&m);
+ GL_ColorMask(1,1,1,0);
+ GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
+ VectorScale(lightcolor, colorscale, color2);
+ GL_LockArrays(0, numverts);
+ for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)