converted vertex fogging to use a fogtable array which matches the fog texture
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 29 Oct 2005 06:51:14 +0000 (06:51 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 29 Oct 2005 06:51:14 +0000 (06:51 +0000)
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
gl_backend.c
gl_rmain.c
r_crosshairs.c
r_light.c
r_lightning.c
r_shadow.c
r_sprites.c
render.h

index b9d3efc..d43ce7d 100644 (file)
@@ -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;
index ee4c944..a2e10d7 100644 (file)
@@ -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);
index 4325e66..3b19095 100644 (file)
@@ -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];
index 3166271..413ee14 100644 (file)
@@ -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)
index ff6d302..4b25a3b 100644 (file)
--- 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);
                }
        }
 }
index 9290d7a..7dc0adb 100644 (file)
@@ -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;
index 463f6e7..3f36eae 100644 (file)
@@ -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)
index 1364ca0..ca0d4b6 100644 (file)
@@ -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);
                }
        }
 }
index 10707a2..9595272 100644 (file)
--- 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;