fog gets additional parameters mindist and maxdist that specify where fog "starts...
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 9 Dec 2007 20:59:57 +0000 (20:59 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 9 Dec 2007 20:59:57 +0000 (20:59 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@7781 d7cf8633-e32d-0410-b094-e92efae38249

cl_main.c
cl_parse.c
client.h
darkplaces.txt
gl_rmain.c
r_sky.c

index 9e1c7fb..e44fdf1 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -1833,13 +1833,23 @@ static void CL_Fog_f (void)
 {
        if (Cmd_Argc () == 1)
        {
-               Con_Printf("\"fog\" is \"%f %f %f %f\"\n", r_refdef.fog_density, r_refdef.fog_red, r_refdef.fog_green, r_refdef.fog_blue);
+               Con_Printf("\"fog\" is \"%f %f %f %f %f %f\"\n", r_refdef.fog_density, r_refdef.fog_red, r_refdef.fog_green, r_refdef.fog_blue, r_refdef.fog_start, r_refdef.fog_end);
                return;
        }
-       r_refdef.fog_density = atof(Cmd_Argv(1));
-       r_refdef.fog_red = atof(Cmd_Argv(2));
-       r_refdef.fog_green = atof(Cmd_Argv(3));
-       r_refdef.fog_blue = atof(Cmd_Argv(4));
+       r_refdef.fog_start = 0;
+       r_refdef.fog_end = 1000000000;
+       if(Cmd_Argc() > 1)
+               r_refdef.fog_density = atof(Cmd_Argv(1));
+       if(Cmd_Argc() > 2)
+               r_refdef.fog_red = atof(Cmd_Argv(2));
+       if(Cmd_Argc() > 3)
+               r_refdef.fog_green = atof(Cmd_Argv(3));
+       if(Cmd_Argc() > 4)
+               r_refdef.fog_blue = atof(Cmd_Argv(4));
+       if(Cmd_Argc() > 5)
+               r_refdef.fog_start = atof(Cmd_Argv(5));
+       if(Cmd_Argc() > 6)
+               r_refdef.fog_end = atof(Cmd_Argv(6));
 }
 
 /*
index 9c54115..0cb0133 100644 (file)
@@ -362,7 +362,11 @@ void CL_ParseEntityLump(char *entdata)
                else if (!strcmp("qlsky", key)) // non-standard, introduced by QuakeLives (EEK)
                        R_SetSkyBox(value);
                else if (!strcmp("fog", key))
-                       sscanf(value, "%f %f %f %f", &r_refdef.fog_density, &r_refdef.fog_red, &r_refdef.fog_green, &r_refdef.fog_blue);
+               {
+                       r_refdef.fog_start = 0;
+                       r_refdef.fog_end = 1000000000;
+                       sscanf(value, "%f %f %f %f %f %f", &r_refdef.fog_density, &r_refdef.fog_red, &r_refdef.fog_green, &r_refdef.fog_blue, &r_refdef.fog_start, &r_refdef.fog_end);
+               }
                else if (!strcmp("fog_density", key))
                        r_refdef.fog_density = atof(value);
                else if (!strcmp("fog_red", key))
index adced35..b98beec 100644 (file)
--- a/client.h
+++ b/client.h
@@ -1315,6 +1315,7 @@ extern qboolean sb_showscores;
 
 float FogPoint_World(const vec3_t p);
 float FogPoint_Model(const vec3_t p);
+float FogForDistance(vec_t dist);
 
 typedef struct r_refdef_stats_s
 {
@@ -1399,6 +1400,7 @@ typedef struct r_refdef_s
        float fog_red;
        float fog_green;
        float fog_blue;
+       float fog_start, fog_end;
        qboolean fogenabled;
        qboolean oldgl_fogenable;
 
index da06f68..8c2153a 100644 (file)
@@ -1081,7 +1081,7 @@ entities                                          print information on network e
 envmap                                            render a cubemap (skybox) of the current scene\r
 exec                                              execute a script file\r
 fly                                               fly mode (flight)\r
-fog                                               set global fog parameters (density red green blue)\r
+fog                                               set global fog parameters (density red green blue mindist maxdist)\r
 force_centerview                                  recenters view (stops looking up/down)\r
 fs_rescan                                         rescans filesystem for new pack archives and any other changes\r
 fullinfo                                          allows client to modify their userinfo\r
index 777dea4..0520595 100644 (file)
@@ -247,18 +247,24 @@ void FOG_clear(void)
                Cvar_Set("gl_fogblue", "0.3");
        }
        r_refdef.fog_density = r_refdef.fog_red = r_refdef.fog_green = r_refdef.fog_blue = 0.0f;
+       r_refdef.fog_start = 0;
+       r_refdef.fog_end = 1000000000;
 }
 
-float FogPoint_World(const vec3_t p)
+float FogForDistance(vec_t dist)
 {
-       unsigned int fogmasktableindex = (unsigned int)(VectorDistance((p), r_view.origin) * r_refdef.fogmasktabledistmultiplier);
+       unsigned int fogmasktableindex = (unsigned int)(bound(0, dist - r_refdef.fog_start, r_refdef.fog_end - r_refdef.fog_start) * r_refdef.fogmasktabledistmultiplier);
        return r_refdef.fogmasktable[min(fogmasktableindex, FOGMASKTABLEWIDTH - 1)];
 }
 
+float FogPoint_World(const vec3_t p)
+{
+       return FogForDistance(VectorDistance((p), r_view.origin));
+}
+
 float FogPoint_Model(const vec3_t p)
 {
-       unsigned int fogmasktableindex = (unsigned int)(VectorDistance((p), rsurface.modelorg) * r_refdef.fogmasktabledistmultiplier);
-       return r_refdef.fogmasktable[min(fogmasktableindex, FOGMASKTABLEWIDTH - 1)];
+       return FogForDistance(VectorDistance((p), rsurface.modelorg));
 }
 
 static void R_BuildBlankTextures(void)
@@ -604,6 +610,8 @@ static const char *builtinshaderstring =
 "uniform float OffsetMapping_Scale;\n"
 "uniform float OffsetMapping_Bias;\n"
 "uniform float FogRangeRecip;\n"
+"uniform float FogStart;\n"
+"uniform float FogLength;\n"
 "\n"
 "uniform myhalf AmbientScale;\n"
 "uniform myhalf DiffuseScale;\n"
@@ -855,7 +863,8 @@ static const char *builtinshaderstring =
 "\n"
 "#ifdef USEFOG\n"
 "      // apply fog\n"
-"      color.rgb = mix(FogColor, color.rgb, myhalf(texture2D(Texture_FogMask, myhvec2(length(EyeVectorModelSpace)*FogRangeRecip, 0.0))));\n"
+"      color.rgb = mix(FogColor, color.rgb, myhalf(texture2D(Texture_FogMask, myhvec2(max(0.0, min(length(EyeVectorModelSpace) - FogStart, FogLength))*FogRangeRecip, 0.0))));\n"
+//"      color.rgb = mix(FogColor, color.rgb, myhalf(texture2D(Texture_FogMask, myhvec2(length(EyeVectorModelSpace)*FogRangeRecip, 0.0))));\n"
 "#endif\n"
 "\n"
 "      gl_FragColor = vec4(color);\n"
@@ -950,6 +959,8 @@ typedef struct r_glsl_permutation_s
        int loc_Color_Pants;
        int loc_Color_Shirt;
        int loc_FogRangeRecip;
+       int loc_FogStart;
+       int loc_FogLength;
        int loc_AmbientScale;
        int loc_DiffuseScale;
        int loc_SpecularScale;
@@ -1081,6 +1092,8 @@ static void R_GLSL_CompilePermutation(const char *filename, int permutation, int
                p->loc_Color_Pants         = qglGetUniformLocationARB(p->program, "Color_Pants");
                p->loc_Color_Shirt         = qglGetUniformLocationARB(p->program, "Color_Shirt");
                p->loc_FogRangeRecip       = qglGetUniformLocationARB(p->program, "FogRangeRecip");
+               p->loc_FogStart            = qglGetUniformLocationARB(p->program, "FogStart");
+               p->loc_FogLength           = qglGetUniformLocationARB(p->program, "FogLength");
                p->loc_AmbientScale        = qglGetUniformLocationARB(p->program, "AmbientScale");
                p->loc_DiffuseScale        = qglGetUniformLocationARB(p->program, "DiffuseScale");
                p->loc_SpecularPower       = qglGetUniformLocationARB(p->program, "SpecularPower");
@@ -1411,6 +1424,8 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, fl
                        qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0);
        }
        if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogRangeRecip, r_refdef.fograngerecip);
+       if (r_glsl_permutation->loc_FogStart >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogStart, r_refdef.fog_start);
+       if (r_glsl_permutation->loc_FogLength >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogLength, r_refdef.fog_end - r_refdef.fog_start);
        if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower);
        if (r_glsl_permutation->loc_OffsetMapping_Scale >= 0) qglUniform1fARB(r_glsl_permutation->loc_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value);
        if (r_glsl_permutation->loc_DistortScaleRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor);
@@ -3273,6 +3288,13 @@ void R_UpdateVariables(void)
                }
        }
 
+       if (r_refdef.fog_start >= r_refdef.fog_end || r_refdef.fog_start < 0)
+       {
+               r_refdef.fog_start = 0;
+               r_refdef.fog_end = 1000000000;
+               // TODO update fog cvars here too
+       }
+
        if (r_refdef.fog_density)
        {
                r_refdef.fogenabled = true;
diff --git a/r_sky.c b/r_sky.c
index 5d6362f..9bd6992 100644 (file)
--- a/r_sky.c
+++ b/r_sky.c
@@ -56,7 +56,7 @@ void R_SkyStartFrame(void)
        skyrendersphere = false;
        skyrenderbox = false;
        skyrendermasked = false;
-       if (r_sky.integer && !r_refdef.fogenabled)
+       if (r_sky.integer && !(r_refdef.fogenabled && r_refdef.fog_end >= 1000000000))
        {
                if (skyboxside[0] || skyboxside[1] || skyboxside[2] || skyboxside[3] || skyboxside[4] || skyboxside[5])
                        skyrenderbox = true;
@@ -286,6 +286,18 @@ static void R_SkyBox(void)
                R_Mesh_TexBind(0, R_GetTexture(skyboxside[i]));
                R_Mesh_Draw(0, 6*4, 2, skyboxelements + i * 6, 0, 0);
        }
+
+       if(r_refdef.fogenabled)
+       {
+               GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+               GL_Color(r_refdef.fogcolor[0] * r_view.colorscale, r_refdef.fogcolor[1] * r_view.colorscale, r_refdef.fogcolor[2] * r_view.colorscale, 1 - FogForDistance(r_refdef.fog_end));
+               for (i = 0;i < 6;i++)
+               {
+                       R_Mesh_TexBind(0, 0);
+                       R_Mesh_Draw(0, 6*4, 2, skyboxelements + i * 6, 0, 0);
+               }
+       }
+
        GL_LockArrays(0, 0);
 }
 
@@ -393,6 +405,7 @@ static void R_SkySphere(void)
                GL_LockArrays(0, skysphere_numverts);
                R_Mesh_Draw(0, skysphere_numverts, skysphere_numtriangles, skysphere_element3i, 0, 0);
                GL_LockArrays(0, 0);
+               R_Mesh_TexBind(1, 0);
        }
        else
        {
@@ -407,6 +420,16 @@ static void R_SkySphere(void)
                R_Mesh_Draw(0, skysphere_numverts, skysphere_numtriangles, skysphere_element3i, 0, 0);
                GL_LockArrays(0, 0);
        }
+
+       if(r_refdef.fogenabled)
+       {
+               R_Mesh_TexBind(0, 0);
+               GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+               GL_Color(r_refdef.fogcolor[0] * r_view.colorscale, r_refdef.fogcolor[1] * r_view.colorscale, r_refdef.fogcolor[2] * r_view.colorscale, 1 - FogForDistance(r_refdef.fog_end));
+               GL_LockArrays(0, skysphere_numverts);
+               R_Mesh_Draw(0, skysphere_numverts, skysphere_numtriangles, skysphere_element3i, 0, 0);
+               GL_LockArrays(0, 0);
+       }
 }
 
 void R_Sky(void)