From 6ede411d2e01c293e840313a7409bb331ed1b97b Mon Sep 17 00:00:00 2001 From: havoc Date: Sat, 29 Oct 2005 06:51:14 +0000 Subject: [PATCH] converted vertex fogging to use a fogtable array which matches the fog texture enabled fog texturing on GLSL lighting path (dot3 path and vertex path still need work) changed EyeVector/LightVector in GLSL shader back to full fp32 precision because at fp16 the vectors were reaching infinity at only a few meters, which obviously broke fogging git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@5780 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_particles.c | 5 +- gl_backend.c | 170 +++++++++++++++++++++++++++++++------------------ gl_rmain.c | 73 +++++++++++++-------- r_crosshairs.c | 2 +- r_light.c | 4 +- r_lightning.c | 4 +- r_shadow.c | 21 +++--- r_sprites.c | 17 +---- render.h | 11 ++-- 9 files changed, 179 insertions(+), 128 deletions(-) diff --git a/cl_particles.c b/cl_particles.c index b9d3efc9..d43ce7d8 100644 --- a/cl_particles.c +++ b/cl_particles.c @@ -1902,7 +1902,7 @@ void R_DrawParticleCallback(const void *calldata1, int calldata2) rmeshstate_t m; #endif pblend_t blendmode; - float org[3], up2[3], v[3], right[3], up[3], fog, ifog, fogvec[3], cr, cg, cb, ca, size; + float org[3], up2[3], v[3], right[3], up[3], fog, ifog, cr, cg, cb, ca, size; particletexture_t *tex; VectorCopy(p->org, org); @@ -1934,8 +1934,7 @@ void R_DrawParticleCallback(const void *calldata1, int calldata2) } if (fogenabled) { - VectorSubtract(org, r_vieworigin, fogvec); - fog = exp(fogdensity/DotProduct(fogvec,fogvec)); + fog = VERTEXFOGTABLE(VectorDistance(org, r_vieworigin)); ifog = 1 - fog; cr = cr * ifog; cg = cg * ifog; diff --git a/gl_backend.c b/gl_backend.c index ee4c944e..a2e10d70 100644 --- a/gl_backend.c +++ b/gl_backend.c @@ -1166,7 +1166,7 @@ void R_Mesh_TexCoordPointer(unsigned int unitnum, unsigned int numcomponents, co void R_Mesh_TexBindAll(unsigned int unitnum, int tex1d, int tex2d, int tex3d, int texcubemap) { gltextureunit_t *unit = gl_state.units + unitnum; - if (unitnum >= backendunits) + if (unitnum >= backendimageunits) return; if (r_showtrispass) return; @@ -1259,7 +1259,7 @@ void R_Mesh_TexBindAll(unsigned int unitnum, int tex1d, int tex2d, int tex3d, in void R_Mesh_TexBind1D(unsigned int unitnum, int texnum) { gltextureunit_t *unit = gl_state.units + unitnum; - if (unitnum >= backendunits) + if (unitnum >= backendimageunits) return; if (r_showtrispass) return; @@ -1267,15 +1267,18 @@ void R_Mesh_TexBind1D(unsigned int unitnum, int texnum) if (unit->t1d != texnum) { GL_ActiveTexture(unitnum); - if (texnum) - { - if (unit->t1d == 0) - qglEnable(GL_TEXTURE_1D); - } - else + if (unitnum < backendunits) { - if (unit->t1d) - qglDisable(GL_TEXTURE_1D); + if (texnum) + { + if (unit->t1d == 0) + qglEnable(GL_TEXTURE_1D); + } + else + { + if (unit->t1d) + qglDisable(GL_TEXTURE_1D); + } } unit->t1d = texnum; qglBindTexture(GL_TEXTURE_1D, unit->t1d); @@ -1285,8 +1288,11 @@ void R_Mesh_TexBind1D(unsigned int unitnum, int texnum) if (unit->t2d) { GL_ActiveTexture(unitnum); - if (unit->t2d) - qglDisable(GL_TEXTURE_2D); + if (unitnum < backendunits) + { + if (unit->t2d) + qglDisable(GL_TEXTURE_2D); + } unit->t2d = 0; qglBindTexture(GL_TEXTURE_2D, unit->t2d); CHECKGLERROR @@ -1295,8 +1301,11 @@ void R_Mesh_TexBind1D(unsigned int unitnum, int texnum) if (unit->t3d) { GL_ActiveTexture(unitnum); - if (unit->t3d) - qglDisable(GL_TEXTURE_3D); + if (unitnum < backendunits) + { + if (unit->t3d) + qglDisable(GL_TEXTURE_3D); + } unit->t3d = 0; qglBindTexture(GL_TEXTURE_3D, unit->t3d); CHECKGLERROR @@ -1305,8 +1314,11 @@ void R_Mesh_TexBind1D(unsigned int unitnum, int texnum) if (unit->tcubemap) { GL_ActiveTexture(unitnum); - if (unit->tcubemap) - qglDisable(GL_TEXTURE_CUBE_MAP_ARB); + if (unitnum < backendunits) + { + if (unit->tcubemap) + qglDisable(GL_TEXTURE_CUBE_MAP_ARB); + } unit->tcubemap = 0; qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap); CHECKGLERROR @@ -1316,7 +1328,7 @@ void R_Mesh_TexBind1D(unsigned int unitnum, int texnum) void R_Mesh_TexBind(unsigned int unitnum, int texnum) { gltextureunit_t *unit = gl_state.units + unitnum; - if (unitnum >= backendunits) + if (unitnum >= backendimageunits) return; if (r_showtrispass) return; @@ -1324,8 +1336,11 @@ void R_Mesh_TexBind(unsigned int unitnum, int texnum) if (unit->t1d) { GL_ActiveTexture(unitnum); - if (unit->t1d) - qglDisable(GL_TEXTURE_1D); + if (unitnum < backendunits) + { + if (unit->t1d) + qglDisable(GL_TEXTURE_1D); + } unit->t1d = 0; qglBindTexture(GL_TEXTURE_1D, unit->t1d); CHECKGLERROR @@ -1334,15 +1349,18 @@ void R_Mesh_TexBind(unsigned int unitnum, int texnum) if (unit->t2d != texnum) { GL_ActiveTexture(unitnum); - if (texnum) - { - if (unit->t2d == 0) - qglEnable(GL_TEXTURE_2D); - } - else + if (unitnum < backendunits) { - if (unit->t2d) - qglDisable(GL_TEXTURE_2D); + if (texnum) + { + if (unit->t2d == 0) + qglEnable(GL_TEXTURE_2D); + } + else + { + if (unit->t2d) + qglDisable(GL_TEXTURE_2D); + } } unit->t2d = texnum; qglBindTexture(GL_TEXTURE_2D, unit->t2d); @@ -1352,8 +1370,11 @@ void R_Mesh_TexBind(unsigned int unitnum, int texnum) if (unit->t3d) { GL_ActiveTexture(unitnum); - if (unit->t3d) - qglDisable(GL_TEXTURE_3D); + if (unitnum < backendunits) + { + if (unit->t3d) + qglDisable(GL_TEXTURE_3D); + } unit->t3d = 0; qglBindTexture(GL_TEXTURE_3D, unit->t3d); CHECKGLERROR @@ -1362,8 +1383,11 @@ void R_Mesh_TexBind(unsigned int unitnum, int texnum) if (unit->tcubemap != 0) { GL_ActiveTexture(unitnum); - if (unit->tcubemap) - qglDisable(GL_TEXTURE_CUBE_MAP_ARB); + if (unitnum < backendunits) + { + if (unit->tcubemap) + qglDisable(GL_TEXTURE_CUBE_MAP_ARB); + } unit->tcubemap = 0; qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap); CHECKGLERROR @@ -1373,7 +1397,7 @@ void R_Mesh_TexBind(unsigned int unitnum, int texnum) void R_Mesh_TexBind3D(unsigned int unitnum, int texnum) { gltextureunit_t *unit = gl_state.units + unitnum; - if (unitnum >= backendunits) + if (unitnum >= backendimageunits) return; if (r_showtrispass) return; @@ -1381,8 +1405,11 @@ void R_Mesh_TexBind3D(unsigned int unitnum, int texnum) if (unit->t1d) { GL_ActiveTexture(unitnum); - if (unit->t1d) - qglDisable(GL_TEXTURE_1D); + if (unitnum < backendunits) + { + if (unit->t1d) + qglDisable(GL_TEXTURE_1D); + } unit->t1d = 0; qglBindTexture(GL_TEXTURE_1D, unit->t1d); CHECKGLERROR @@ -1391,8 +1418,11 @@ void R_Mesh_TexBind3D(unsigned int unitnum, int texnum) if (unit->t2d) { GL_ActiveTexture(unitnum); - if (unit->t2d) - qglDisable(GL_TEXTURE_2D); + if (unitnum < backendunits) + { + if (unit->t2d) + qglDisable(GL_TEXTURE_2D); + } unit->t2d = 0; qglBindTexture(GL_TEXTURE_2D, unit->t2d); CHECKGLERROR @@ -1401,15 +1431,18 @@ void R_Mesh_TexBind3D(unsigned int unitnum, int texnum) if (unit->t3d != texnum) { GL_ActiveTexture(unitnum); - if (texnum) - { - if (unit->t3d == 0) - qglEnable(GL_TEXTURE_3D); - } - else + if (unitnum < backendunits) { - if (unit->t3d) - qglDisable(GL_TEXTURE_3D); + if (texnum) + { + if (unit->t3d == 0) + qglEnable(GL_TEXTURE_3D); + } + else + { + if (unit->t3d) + qglDisable(GL_TEXTURE_3D); + } } unit->t3d = texnum; qglBindTexture(GL_TEXTURE_3D, unit->t3d); @@ -1419,8 +1452,11 @@ void R_Mesh_TexBind3D(unsigned int unitnum, int texnum) if (unit->tcubemap != 0) { GL_ActiveTexture(unitnum); - if (unit->tcubemap) - qglDisable(GL_TEXTURE_CUBE_MAP_ARB); + if (unitnum < backendunits) + { + if (unit->tcubemap) + qglDisable(GL_TEXTURE_CUBE_MAP_ARB); + } unit->tcubemap = 0; qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap); CHECKGLERROR @@ -1430,7 +1466,7 @@ void R_Mesh_TexBind3D(unsigned int unitnum, int texnum) void R_Mesh_TexBindCubeMap(unsigned int unitnum, int texnum) { gltextureunit_t *unit = gl_state.units + unitnum; - if (unitnum >= backendunits) + if (unitnum >= backendimageunits) return; if (r_showtrispass) return; @@ -1438,8 +1474,11 @@ void R_Mesh_TexBindCubeMap(unsigned int unitnum, int texnum) if (unit->t1d) { GL_ActiveTexture(unitnum); - if (unit->t1d) - qglDisable(GL_TEXTURE_1D); + if (unitnum < backendunits) + { + if (unit->t1d) + qglDisable(GL_TEXTURE_1D); + } unit->t1d = 0; qglBindTexture(GL_TEXTURE_1D, unit->t1d); CHECKGLERROR @@ -1448,8 +1487,11 @@ void R_Mesh_TexBindCubeMap(unsigned int unitnum, int texnum) if (unit->t2d) { GL_ActiveTexture(unitnum); - if (unit->t2d) - qglDisable(GL_TEXTURE_2D); + if (unitnum < backendunits) + { + if (unit->t2d) + qglDisable(GL_TEXTURE_2D); + } unit->t2d = 0; qglBindTexture(GL_TEXTURE_2D, unit->t2d); CHECKGLERROR @@ -1458,8 +1500,11 @@ void R_Mesh_TexBindCubeMap(unsigned int unitnum, int texnum) if (unit->t3d) { GL_ActiveTexture(unitnum); - if (unit->t3d) - qglDisable(GL_TEXTURE_3D); + if (unitnum < backendunits) + { + if (unit->t3d) + qglDisable(GL_TEXTURE_3D); + } unit->t3d = 0; qglBindTexture(GL_TEXTURE_3D, unit->t3d); CHECKGLERROR @@ -1468,15 +1513,18 @@ void R_Mesh_TexBindCubeMap(unsigned int unitnum, int texnum) if (unit->tcubemap != texnum) { GL_ActiveTexture(unitnum); - if (texnum) - { - if (unit->tcubemap == 0) - qglEnable(GL_TEXTURE_CUBE_MAP_ARB); - } - else + if (unitnum < backendunits) { - if (unit->tcubemap) - qglDisable(GL_TEXTURE_CUBE_MAP_ARB); + if (texnum) + { + if (unit->tcubemap == 0) + qglEnable(GL_TEXTURE_CUBE_MAP_ARB); + } + else + { + if (unit->tcubemap) + qglDisable(GL_TEXTURE_CUBE_MAP_ARB); + } } unit->tcubemap = texnum; qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap); diff --git a/gl_rmain.c b/gl_rmain.c index 4325e66b..3b19095a 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -152,6 +152,9 @@ vec3_t fogcolor; vec_t fogdensity; vec_t fogrange; vec_t fograngerecip; +int fogtableindex; +vec_t fogtabledistmultiplier; +float fogtable[FOGTABLEWIDTH]; float fog_density, fog_red, fog_green, fog_blue; qboolean fogenabled; qboolean oldgl_fogenable; @@ -186,10 +189,12 @@ void R_UpdateFog(void) { fogenabled = true; fogdensity = -4000.0f / (fog_density * fog_density); - // this is the point where the fog reaches 0.991373 alpha, which we + // this is the point where the fog reaches 0.9986 alpha, which we // consider a good enough cutoff point for the texture + // (0.9986 * 256 == 255.6) fogrange = 400 / fog_density; fograngerecip = 1.0f / fogrange; + fogtabledistmultiplier = FOGTABLEWIDTH * fograngerecip; // fog color was already set } else @@ -213,6 +218,9 @@ void FOG_clear(void) // FIXME: move this to client? void FOG_registercvars(void) { + int x; + double r, alpha; + if (gamemode == GAME_NEHAHRA) { Cvar_RegisterVariable (&gl_fogenable); @@ -223,6 +231,15 @@ void FOG_registercvars(void) Cvar_RegisterVariable (&gl_fogstart); Cvar_RegisterVariable (&gl_fogend); } + + r = (-1.0/256.0) * (FOGTABLEWIDTH * FOGTABLEWIDTH); + for (x = 0;x < FOGTABLEWIDTH;x++) + { + alpha = exp(r / ((double)x*(double)x)); + if (x == FOGTABLEWIDTH - 1) + alpha = 1; + fogtable[x] = bound(0, alpha, 1); + } } static void R_BuildBlankTextures(void) @@ -347,15 +364,18 @@ static void R_BuildNormalizationCube(void) static void R_BuildFogTexture(void) { -#define FOGWIDTH 64 int x, b; - double r; + double r, alpha; +#define FOGWIDTH 64 qbyte data1[FOGWIDTH][4]; qbyte data2[FOGWIDTH][4]; - r = (-65536.0 / (FOGWIDTH*FOGWIDTH)); + r = (-1.0/256.0) * (FOGWIDTH * FOGWIDTH); for (x = 0;x < FOGWIDTH;x++) { - b = (int)(256.0 * exp(r / ((double)x*(double)x))); + alpha = exp(r / ((double)x*(double)x)); + if (x == FOGWIDTH - 1) + alpha = 1; + b = (int)(256.0 * alpha); b = bound(0, b, 255); data1[x][0] = 255 - b; data1[x][1] = 255 - b; @@ -366,8 +386,8 @@ static void R_BuildFogTexture(void) data2[x][2] = b; data2[x][3] = 255; } - r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP, NULL); - r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP, NULL); + r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL); + r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL); } void gl_main_start(void) @@ -1125,8 +1145,7 @@ void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, floa { for (i = 0, v = vertex, c = color;i < 8;i++, v += 4, c += 4) { - VectorSubtract(v, r_vieworigin, diff); - f2 = exp(fogdensity/DotProduct(diff, diff)); + f2 = VERTEXFOGTABLE(VectorDistance(v, r_vieworigin)); f1 = 1 - f2; c[0] = c[0] * f1 + fogcolor[0] * f2; c[1] = c[1] * f1 + fogcolor[1] * f2; @@ -1177,7 +1196,7 @@ void R_DrawNoModelCallback(const void *calldata1, int calldata2) { const entity_render_t *ent = (entity_render_t *)calldata1; int i; - float f1, f2, *c, diff[3]; + float f1, f2, *c; float color4f[6*4]; rmeshstate_t m; R_Mesh_Matrix(&ent->matrix); @@ -1205,8 +1224,7 @@ void R_DrawNoModelCallback(const void *calldata1, int calldata2) { memcpy(color4f, nomodelcolor4f, sizeof(float[6*4])); m.pointer_color = color4f; - VectorSubtract(ent->origin, r_vieworigin, diff); - f2 = exp(fogdensity/DotProduct(diff, diff)); + f2 = VERTEXFOGTABLE(VectorDistance(ent->origin, r_vieworigin)); f1 = 1 - f2; for (i = 0, c = color4f;i < 6;i++, c += 4) { @@ -1269,16 +1287,14 @@ void R_CalcBeam_Vertex3f (float *vert, const vec3_t org1, const vec3_t org2, flo float spritetexcoord2f[4*2] = {0, 1, 0, 0, 1, 0, 1, 1}; -void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, int depthdisable, const vec3_t origin, const vec3_t left, const vec3_t up, float scalex1, float scalex2, float scaley1, float scaley2, float cr, float cg, float cb, float ca) +void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, rtexture_t *fogtexture, int depthdisable, const vec3_t origin, const vec3_t left, const vec3_t up, float scalex1, float scalex2, float scaley1, float scaley2, float cr, float cg, float cb, float ca) { - float diff[3]; + float fog = 0.0f, ifog; rmeshstate_t m; if (fogenabled) - { - VectorSubtract(origin, r_vieworigin, diff); - ca *= 1 - exp(fogdensity/DotProduct(diff,diff)); - } + fog = VERTEXFOGTABLE(VectorDistance(origin, r_vieworigin)); + ifog = 1 - fog; R_Mesh_Matrix(&r_identitymatrix); GL_BlendFunc(blendfunc1, blendfunc2); @@ -1303,8 +1319,16 @@ void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, int depth m.pointer_texcoord[0] = spritetexcoord2f; m.pointer_vertex = varray_vertex3f; R_Mesh_State(&m); - GL_Color(cr, cg, cb, ca); + GL_Color(cr * ifog, cg * ifog, cb * ifog, ca); R_Mesh_Draw(0, 4, 2, polygonelements); + + if (blendfunc2 == GL_ONE_MINUS_SRC_ALPHA) + { + R_Mesh_TexBind(0, R_GetTexture(fogtexture)); + GL_BlendFunc(blendfunc1, GL_ONE); + GL_Color(fogcolor[0] * fog, fogcolor[1] * fog, fogcolor[2] * fog, ca); + R_Mesh_Draw(0, 4, 2, polygonelements); + } } int R_Mesh_AddVertex3f(rmesh_t *mesh, const float *v) @@ -1645,7 +1669,6 @@ void RSurf_SetColorPointer(const entity_render_t *ent, const msurface_t *surface int i; float f; float *v, *c, *c2; - vec3_t diff; if (lightmode >= 2) { // model lighting @@ -1723,8 +1746,7 @@ void RSurf_SetColorPointer(const entity_render_t *ent, const msurface_t *surface { for (i = 0, v = (rsurface_vertex3f + 3 * surface->num_firstvertex), c = (rsurface_lightmapcolor4f + 4 * surface->num_firstvertex), c2 = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4, c2 += 4) { - VectorSubtract(v, modelorg, diff); - f = 1 - exp(fogdensity/DotProduct(diff, diff)); + f = 1 - VERTEXFOGTABLE(VectorDistance(v, modelorg)); c2[0] = c[0] * f; c2[1] = c[1] * f; c2[2] = c[2] * f; @@ -1735,8 +1757,7 @@ void RSurf_SetColorPointer(const entity_render_t *ent, const msurface_t *surface { for (i = 0, v = (rsurface_vertex3f + 3 * surface->num_firstvertex), c2 = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c2 += 4) { - VectorSubtract(v, modelorg, diff); - f = 1 - exp(fogdensity/DotProduct(diff, diff)); + f = 1 - VERTEXFOGTABLE(VectorDistance(v, modelorg)); c2[0] = f; c2[1] = f; c2[2] = f; @@ -1977,7 +1998,6 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { int i; - float diff[3]; float f, *v, *c; surface = texturesurfacelist[texturesurfaceindex]; RSurf_SetVertexPointer(ent, texture, surface, modelorg); @@ -1986,8 +2006,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text R_Mesh_ColorPointer(varray_color4f); for (i = 0, v = (rsurface_vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4) { - VectorSubtract(v, modelorg, diff); - f = exp(fogdensity/DotProduct(diff, diff)); + f = VERTEXFOGTABLE(VectorDistance(v, modelorg)); c[0] = layercolor[0]; c[1] = layercolor[1]; c[2] = layercolor[2]; diff --git a/r_crosshairs.c b/r_crosshairs.c index 31662713..413ee14e 100644 --- a/r_crosshairs.c +++ b/r_crosshairs.c @@ -90,7 +90,7 @@ void R_DrawWorldCrosshair(void) VectorCopy(trace.endpos, spriteorigin); // draw the sprite - R_DrawSprite(GL_SRC_ALPHA, GL_ONE, pic->tex, true, spriteorigin, r_viewright, r_viewup, spritescale, -spritescale, -spritescale, spritescale, color[0], color[1], color[2], color[3]); + R_DrawSprite(GL_ONE, GL_ONE, pic->tex, NULL, true, spriteorigin, r_viewright, r_viewup, spritescale, -spritescale, -spritescale, spritescale, color[0], color[1], color[2], color[3]); } void R_Draw2DCrosshair(void) diff --git a/r_light.c b/r_light.c index ff6d3021..4b25a3ba 100644 --- a/r_light.c +++ b/r_light.c @@ -92,7 +92,7 @@ void R_DrawCoronas(void) { cscale = light->rtlight.corona * r_coronas.value * 0.25f; scale = light->rtlight.radius * light->rtlight.coronasizescale; - R_DrawSprite(GL_ONE, GL_ONE, lightcorona, true, light->rtlight.shadoworigin, r_viewright, r_viewup, scale, -scale, -scale, scale, light->rtlight.color[0] * cscale, light->rtlight.color[1] * cscale, light->rtlight.color[2] * cscale, 1); + R_DrawSprite(GL_ONE, GL_ONE, lightcorona, NULL, true, light->rtlight.shadoworigin, r_viewright, r_viewup, scale, -scale, -scale, scale, light->rtlight.color[0] * cscale, light->rtlight.color[1] * cscale, light->rtlight.color[2] * cscale, 1); } } for (i = 0;i < r_refdef.numlights;i++) @@ -107,7 +107,7 @@ void R_DrawCoronas(void) cscale *= 4.0f; scale *= 2.0f; } - R_DrawSprite(GL_ONE, GL_ONE, lightcorona, true, light->origin, r_viewright, r_viewup, scale, -scale, -scale, scale, light->color[0] * cscale, light->color[1] * cscale, light->color[2] * cscale, 1); + R_DrawSprite(GL_ONE, GL_ONE, lightcorona, NULL, true, light->origin, r_viewright, r_viewup, scale, -scale, -scale, scale, light->color[0] * cscale, light->color[1] * cscale, light->color[2] * cscale, 1); } } } diff --git a/r_lightning.c b/r_lightning.c index 9290d7a0..7dc0adbf 100644 --- a/r_lightning.c +++ b/r_lightning.c @@ -216,12 +216,10 @@ void R_CalcLightningBeamPolygonTexCoord2f(float *tc, float t1, float t2) void R_FogLightningBeam_Vertex3f_Color4f(const float *v, float *c, int numverts, float r, float g, float b, float a) { int i; - vec3_t fogvec; float ifog; for (i = 0;i < numverts;i++, v += 3, c += 4) { - VectorSubtract(v, r_vieworigin, fogvec); - ifog = 1 - exp(fogdensity/DotProduct(fogvec,fogvec)); + ifog = 1 - VERTEXFOGTABLE(VectorDistance(v, r_vieworigin)); c[0] = r * ifog; c[1] = g * ifog; c[2] = b * ifog; diff --git a/r_shadow.c b/r_shadow.c index 463f6e74..3f36eae5 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -297,11 +297,11 @@ const char *builtinshader_light_vert = "\n" "varying vec2 TexCoord;\n" "varying myhvec3 CubeVector;\n" -"varying myhvec3 LightVector;\n" +"varying vec3 LightVector;\n" "\n" "#if defined(USESPECULAR) || defined(USEFOG) || defined(USEOFFSETMAPPING)\n" "uniform vec3 EyePosition;\n" -"varying myhvec3 EyeVector;\n" +"varying vec3 EyeVector;\n" "#endif\n" "\n" "// TODO: get rid of tangentt (texcoord2) and use a crossproduct to regenerate it from tangents (texcoord1) and normal (texcoord3)\n" @@ -385,9 +385,9 @@ const char *builtinshader_light_frag = "\n" "varying vec2 TexCoord;\n" "varying myhvec3 CubeVector;\n" -"varying myhvec3 LightVector;\n" +"varying vec3 LightVector;\n" "#if defined(USESPECULAR) || defined(USEFOG) || defined(USEOFFSETMAPPING)\n" -"varying myhvec3 EyeVector;\n" +"varying vec3 EyeVector;\n" "#endif\n" "\n" "void main(void)\n" @@ -1223,8 +1223,7 @@ void R_Shadow_Stage_Lighting(int stenciltest) m.tex[1] = R_GetTexture(r_texture_white); // diffuse m.tex[2] = R_GetTexture(r_texture_white); // gloss m.texcubemap[3] = R_GetTexture(r_shadow_lightcubemap); // light filter - // TODO: support fog (after renderer is converted to texture fog) - m.tex[4] = R_GetTexture(r_texture_white); // fog + m.tex[4] = R_GetTexture(r_texture_fogattenuation); // fog //m.texmatrix[3] = r_shadow_entitytolight; // light filter matrix R_Mesh_State(&m); GL_BlendFunc(GL_ONE, GL_ONE); @@ -1234,10 +1233,10 @@ void R_Shadow_Stage_Lighting(int stenciltest) // 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 (fog && r_shadow_program_light[r_shadow_lightpermutation | SHADERPERMUTATION_FOG]) - // r_shadow_lightpermutation |= SHADERPERMUTATION_FOG; if (r_shadow_lightcubemap != 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]) @@ -1251,7 +1250,7 @@ void R_Shadow_Stage_Lighting(int stenciltest) // TODO: support fog (after renderer is converted to texture fog) if (r_shadow_lightpermutation & SHADERPERMUTATION_FOG) { - qglUniform1fARB(qglGetUniformLocationARB(r_shadow_lightprog, "FogRangeRecip"), 0);CHECKGLERROR + 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 @@ -3089,7 +3088,7 @@ void R_Shadow_SelectLight(dlight_t *light) void R_Shadow_DrawCursorCallback(const void *calldata1, int calldata2) { float scale = r_editlights_cursorgrid.value * 0.5f; - R_DrawSprite(GL_SRC_ALPHA, GL_ONE, lighttextures[0], false, r_editlights_cursorlocation, r_viewright, r_viewup, scale, -scale, -scale, scale, 1, 1, 1, 0.5f); + R_DrawSprite(GL_ONE, GL_ONE, lighttextures[0], NULL, false, r_editlights_cursorlocation, r_viewright, r_viewup, scale, -scale, -scale, scale, 1, 1, 1, 0.5f); } void R_Shadow_DrawLightSpriteCallback(const void *calldata1, int calldata2) @@ -3102,7 +3101,7 @@ void R_Shadow_DrawLightSpriteCallback(const void *calldata1, int calldata2) intensity = 0.75 + 0.25 * sin(realtime * M_PI * 4.0); if (!light->shadow) intensity *= 0.5f; - R_DrawSprite(GL_SRC_ALPHA, GL_ONE, lighttextures[calldata2], false, light->origin, r_viewright, r_viewup, 8, -8, -8, 8, intensity, intensity, intensity, 0.5); + R_DrawSprite(GL_ONE, GL_ONE, lighttextures[calldata2], NULL, false, light->origin, r_viewright, r_viewup, 8, -8, -8, 8, intensity, intensity, intensity, 0.5); } void R_Shadow_DrawLightSprites(void) diff --git a/r_sprites.c b/r_sprites.c index 1364ca05..ca0d4b67 100644 --- a/r_sprites.c +++ b/r_sprites.c @@ -7,8 +7,6 @@ void R_DrawSpriteModelCallback(const void *calldata1, int calldata2) int i; vec3_t left, up, org, color, diffusecolor, diffusenormal; mspriteframe_t *frame; - vec3_t diff; - float fog, ifog; float scale; // nudge it toward the view to make sure it isn't in a wall @@ -88,17 +86,6 @@ void R_DrawSpriteModelCallback(const void *calldata1, int calldata2) color[1] *= ent->colormod[1]; color[2] *= ent->colormod[2]; - if (fogenabled) - { - VectorSubtract(ent->origin, r_vieworigin, diff); - fog = exp(fogdensity/DotProduct(diff,diff)); - if (fog > 1) - fog = 1; - } - else - fog = 0; - ifog = 1 - fog; - // LordHavoc: interpolated sprite rendering for (i = 0;i < 4;i++) { @@ -106,9 +93,7 @@ void R_DrawSpriteModelCallback(const void *calldata1, int calldata2) { frame = ent->model->sprite.sprdata_frames + ent->frameblend[i].frame; // FIXME: negate left and right in loader - R_DrawSprite(GL_SRC_ALPHA, (ent->effects & EF_ADDITIVE) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, frame->texture, (ent->effects & EF_NODEPTHTEST), org, left, up, frame->left, frame->right, frame->down, frame->up, color[0] * ifog, color[1] * ifog, color[2] * ifog, ent->alpha * ent->frameblend[i].lerp); - if (fog * ent->frameblend[i].lerp >= 0.01f) - R_DrawSprite(GL_SRC_ALPHA, GL_ONE, frame->fogtexture, (ent->effects & EF_NODEPTHTEST), org, left, up, frame->left, frame->right, frame->down, frame->up, fogcolor[0],fogcolor[1],fogcolor[2], fog * ent->alpha * ent->frameblend[i].lerp); + R_DrawSprite(GL_SRC_ALPHA, (ent->effects & EF_ADDITIVE) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, frame->texture, frame->fogtexture, (ent->effects & EF_NODEPTHTEST), org, left, up, frame->left, frame->right, frame->down, frame->up, color[0], color[1], color[2], ent->alpha * ent->frameblend[i].lerp); } } } diff --git a/render.h b/render.h index 10707a28..9595272a 100644 --- a/render.h +++ b/render.h @@ -194,13 +194,16 @@ void R_DrawExplosions(void); int R_CullBox(const vec3_t mins, const vec3_t maxs); -extern qboolean fogenabled; +#define FOGTABLEWIDTH 1024 extern vec3_t fogcolor; extern vec_t fogdensity; extern vec_t fogrange; extern vec_t fograngerecip; -#define calcfog(v) (exp(-(fogdensity*fogdensity*(((v)[0] - r_vieworigin[0])*((v)[0] - r_vieworigin[0])+((v)[1] - r_vieworigin[1])*((v)[1] - r_vieworigin[1])+((v)[2] - r_vieworigin[2])*((v)[2] - r_vieworigin[2]))))) -#define calcfogbyte(v) ((qbyte) (bound(0, ((int) ((float) (calcfog((v)) * 255.0f))), 255))) +extern int fogtableindex; +extern vec_t fogtabledistmultiplier; +extern float fogtable[FOGTABLEWIDTH]; +extern qboolean fogenabled; +#define VERTEXFOGTABLE(dist) (fogtableindex = (int)((dist) * fogtabledistmultiplier), fogtable[bound(0, fogtableindex, FOGTABLEWIDTH - 1)]) #include "r_modules.h" @@ -241,7 +244,7 @@ void R_DrawWorldCrosshair(void); void R_Draw2DCrosshair(void); void R_CalcBeam_Vertex3f(float *vert, const vec3_t org1, const vec3_t org2, float width); -void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, int depthdisable, const vec3_t origin, const vec3_t left, const vec3_t up, float scalex1, float scalex2, float scaley1, float scaley2, float cr, float cg, float cb, float ca); +void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, rtexture_t *fogtexture, int depthdisable, const vec3_t origin, const vec3_t left, const vec3_t up, float scalex1, float scalex2, float scaley1, float scaley2, float cr, float cg, float cb, float ca); struct entity_render_s; struct texture_s; -- 2.39.2