From b71d7f0f30d41defd8132e7d5af356c48c8f12af Mon Sep 17 00:00:00 2001 From: havoc Date: Thu, 2 Feb 2006 14:57:04 +0000 Subject: [PATCH] vertex lighting path now does pants/shirt rendering faster than before doubled brightness of vertex lighting path to make it look roughly like the other paths (unsure why it was darker however) optimized lighting code setup a bit (less silly conditional returns) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@5939 d7cf8633-e32d-0410-b094-e92efae38249 --- r_shadow.c | 233 +++++++++++++++++++++++++++++------------------------ 1 file changed, 128 insertions(+), 105 deletions(-) diff --git a/r_shadow.c b/r_shadow.c index bd55014c..88bc0735 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -1424,7 +1424,7 @@ extern float *rsurface_tvector3f; 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; @@ -1440,9 +1440,9 @@ static void R_Shadow_RenderSurfacesLighting_Light_Vertex_Shading(const msurface_ 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)); @@ -1466,15 +1466,15 @@ static void R_Shadow_RenderSurfacesLighting_Light_Vertex_Shading(const msurface_ 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) { @@ -1500,15 +1500,15 @@ static void R_Shadow_RenderSurfacesLighting_Light_Vertex_Shading(const msurface_ 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) { @@ -2418,29 +2418,104 @@ static void R_Shadow_RenderSurfacesLighting_Light_Dot3(const entity_render_t *en } } +void R_Shadow_RenderSurfacesLighting_Light_Vertex_Pass(const msurface_t *surface, vec3_t diffusecolor2, vec3_t ambientcolor2) +{ + int renders; + const int *elements = surface->groupmesh->data_element3i + surface->num_firsttriangle * 3; + R_Shadow_RenderSurfacesLighting_Light_Vertex_Shading(surface, diffusecolor2, ambientcolor2); + for (renders = 0;renders < 64 && (ambientcolor2[0] > renders || ambientcolor2[1] > renders || ambientcolor2[2] > renders || diffusecolor2[0] > renders || diffusecolor2[1] > renders || diffusecolor2[2] > renders);renders++) + { + int i; + float *c; +#if 1 + // due to low fillrate on the cards this vertex lighting path is + // designed for, we manually cull all triangles that do not + // contain a lit vertex + int draw; + const int *e; + int newnumtriangles; + int *newe; + int newelements[3072]; + draw = false; + newnumtriangles = 0; + newe = newelements; + for (i = 0, e = elements;i < surface->num_triangles;i++, e += 3) + { + if (newnumtriangles >= 1024) + { + GL_LockArrays(surface->num_firstvertex, surface->num_vertices); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, newnumtriangles, newelements); + GL_LockArrays(0, 0); + newnumtriangles = 0; + newe = newelements; + } + if (VectorLength2(varray_color4f + e[0] * 4) + VectorLength2(varray_color4f + e[1] * 4) + VectorLength2(varray_color4f + e[2] * 4) >= 0.01) + { + newe[0] = e[0]; + newe[1] = e[1]; + newe[2] = e[2]; + newnumtriangles++; + newe += 3; + draw = true; + } + } + if (newnumtriangles >= 1) + { + GL_LockArrays(surface->num_firstvertex, surface->num_vertices); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, newnumtriangles, newelements); + GL_LockArrays(0, 0); + draw = true; + } + if (!draw) + break; +#else + for (i = 0, c = varray_color4f + 4 * surface->num_firstvertex;i < surface->num_vertices;i++, c += 4) + if (VectorLength2(c)) + goto goodpass; + break; +goodpass: + GL_LockArrays(surface->num_firstvertex, surface->num_vertices); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, elements); + GL_LockArrays(0, 0); +#endif + // now reduce the intensity for the next overbright pass + for (i = 0, c = varray_color4f + 4 * surface->num_firstvertex;i < surface->num_vertices;i++, c += 4) + { + c[0] = max(0, c[0] - 1); + c[1] = max(0, c[1] - 1); + c[2] = max(0, c[2] - 1); + } + } +} + static void R_Shadow_RenderSurfacesLighting_Light_Vertex(const entity_render_t *ent, const texture_t *texture, int numsurfaces, msurface_t **surfacelist, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float specularscale) { 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) + qboolean dobase = basetexture != r_texture_black; + qboolean dopants = pantstexture != r_texture_black; + qboolean doshirt = shirttexture != r_texture_black; + if (!dobase && !dopants && !doshirt) return; - VectorScale(lightcolorbase, r_shadow_rtlight->ambientscale, ambientcolor2); - VectorScale(lightcolorbase, r_shadow_rtlight->diffusescale, diffusecolor2); - GL_BlendFunc(GL_ONE, GL_ONE); + if (dobase) + { + VectorScale(lightcolorbase, r_shadow_rtlight->ambientscale * 2, ambientcolorbase); + VectorScale(lightcolorbase, r_shadow_rtlight->diffusescale * 2, diffusecolorbase); + } + if (dopants) + { + VectorScale(lightcolorpants, r_shadow_rtlight->ambientscale * 2, ambientcolorpants); + VectorScale(lightcolorpants, r_shadow_rtlight->diffusescale * 2, diffusecolorpants); + } + if (doshirt) + { + 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) @@ -2470,7 +2545,6 @@ static void R_Shadow_RenderSurfacesLighting_Light_Vertex(const entity_render_t * 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) { @@ -2500,69 +2574,20 @@ static void R_Shadow_RenderSurfacesLighting_Light_Vertex(const entity_render_t * #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++) + if (dobase) { - 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(basetexture)); + R_Shadow_RenderSurfacesLighting_Light_Vertex_Pass(surface, diffusecolorbase, ambientcolorbase); + } + if (dopants) + { + 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); } } } @@ -2574,10 +2599,6 @@ void R_Shadow_RenderSurfacesLighting(const entity_render_t *ent, const texture_t rtexture_t *basetexture; rtexture_t *glosstexture; float specularscale; - if ((texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (ent->flags & RENDER_NOCULLFACE)) - qglDisable(GL_CULL_FACE); - else - qglEnable(GL_CULL_FACE); glosstexture = r_texture_black; specularscale = 0; if (r_shadow_gloss.integer > 0) @@ -2603,6 +2624,12 @@ void R_Shadow_RenderSurfacesLighting(const entity_render_t *ent, const texture_t 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; + 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); if ((VectorLength2(ent->colormap_pantscolor) + VectorLength2(ent->colormap_shirtcolor)) >= (1.0f / 1048576.0f)) { lightcolorpants[0] = r_shadow_rtlight->currentcolor[0] * ent->colormap_pantscolor[0] * texture->currentalpha; @@ -2611,8 +2638,6 @@ void R_Shadow_RenderSurfacesLighting(const entity_render_t *ent, const texture_t 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 ((r_shadow_rtlight->ambientscale + r_shadow_rtlight->diffusescale) * (VectorLength2(lightcolorbase) + VectorLength2(lightcolorpants) + VectorLength2(lightcolorshirt)) + specularscale * VectorLength2(lightcolorbase) < (1.0f / 1048576.0f)) - return; basetexture = texture->skin.base; switch (r_shadow_rendermode) { @@ -2635,8 +2660,6 @@ void R_Shadow_RenderSurfacesLighting(const entity_render_t *ent, const texture_t } else { - if ((r_shadow_rtlight->ambientscale + r_shadow_rtlight->diffusescale) * VectorLength2(lightcolorbase) + specularscale * VectorLength2(lightcolorbase) < (1.0f / 1048576.0f)) - return; basetexture = texture->skin.merged ? texture->skin.merged : texture->skin.base; switch (r_shadow_rendermode) { -- 2.39.2