diff --git a/source/gl_fog.c b/source/gl_fog.c index 31406be..2a3fb5d 100644 --- a/source/gl_fog.c +++ b/source/gl_fog.c @@ -25,23 +25,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // //============================================================================== -#define DEFAULT_DENSITY 0.0 -#define DEFAULT_GRAY 0.3 +extern refdef_t r_refdef; -float fog_start; -float fog_end; -float fog_density_gl; -float fog_red; -float fog_green; -float fog_blue; +float old_start; +float old_end; +float old_red; +float old_green; +float old_blue; -float old_density; -float old_red; -float old_green; -float old_blue; - -float fade_time; //duration of fade -float fade_done; //time when fade will be done +float fade_time; // duration of fade +float fade_done; // time when fade will be done /* ============= @@ -49,7 +42,7 @@ Fog_Update update internal variables ============= */ -void Fog_Update (float density, float red, float green, float blue, float time) +void Fog_Update (float start, float end, float red, float green, float blue, float time) { //save previous settings for fade if (time > 0) @@ -60,24 +53,27 @@ void Fog_Update (float density, float red, float green, float blue, float time) float f; f = (fade_done - cl.time) / fade_time; - old_density = f * old_density + (1.0 - f) * fog_density_gl; - old_red = f * old_red + (1.0 - f) * fog_red; - old_green = f * old_green + (1.0 - f) * fog_green; - old_blue = f * old_blue + (1.0 - f) * fog_blue; + old_start = f * old_start + (1.0 - f) * r_refdef.fog_start; + old_end = f * old_end + (1.0 - f) * r_refdef.fog_end; + old_red = f * old_red + (1.0 - f) * r_refdef.fog_red; + old_green = f * old_green + (1.0 - f) * r_refdef.fog_green; + old_blue = f * old_blue + (1.0 - f) * r_refdef.fog_blue; } else { - old_density = fog_density_gl; - old_red = fog_red; - old_green = fog_green; - old_blue = fog_blue; + old_start = r_refdef.fog_start; + old_end = r_refdef.fog_end; + old_red = r_refdef.fog_red; + old_green = r_refdef.fog_green; + old_blue = r_refdef.fog_blue; } } - fog_density_gl = density; - fog_red = red; - fog_green = green; - fog_blue = blue; + r_refdef.fog_start = start; + r_refdef.fog_end = end; + r_refdef.fog_red = red; + r_refdef.fog_green = green; + r_refdef.fog_blue = blue; fade_time = time; fade_done = cl.time + time; } @@ -90,15 +86,16 @@ handle an SVC_FOG message from server */ void Fog_ParseServerMessage (void) { - float density, red, green, blue, time; + float start, end, red, green, blue, time; - density = MSG_ReadByte() / 255.0; + start = MSG_ReadByte() / 255.0; + end = MSG_ReadByte() / 255.0; red = MSG_ReadByte() / 255.0; green = MSG_ReadByte() / 255.0; blue = MSG_ReadByte() / 255.0; - time = max(0.0, MSG_ReadShort() / 100.0); + time = MSG_ReadShort() / 100.0; - Fog_Update (density, red, green, blue, time); + Fog_Update (start, end, red, green, blue, time); } /* @@ -114,49 +111,67 @@ void Fog_FogCommand_f (void) default: case 1: Con_Printf("usage:\n"); - Con_Printf(" fog \n"); + Con_Printf(" fog \n"); + Con_Printf(" fog \n"); Con_Printf(" fog \n"); - Con_Printf(" fog \n"); + Con_Printf(" fog \n"); + Con_Printf(" fog \n"); + Con_Printf(" fog \n"); Con_Printf("current values:\n"); - Con_Printf(" \"density\" is \"%f\"\n", fog_density_gl); - Con_Printf(" \"red\" is \"%f\"\n", fog_red); - Con_Printf(" \"green\" is \"%f\"\n", fog_green); - Con_Printf(" \"blue\" is \"%f\"\n", fog_blue); + Con_Printf(" \"start\" is \"%f\"\n", r_refdef.fog_start); + Con_Printf(" \"end\" is \"%f\"\n", r_refdef.fog_end); + Con_Printf(" \"red\" is \"%f\"\n", r_refdef.fog_red); + Con_Printf(" \"green\" is \"%f\"\n", r_refdef.fog_green); + Con_Printf(" \"blue\" is \"%f\"\n", r_refdef.fog_blue); + Con_Printf(" \"fade\" is \"%f\"\n", fade_time); break; - case 2: - Fog_Update(max(0.0, atof(Cmd_Argv(1))), - fog_red, - fog_green, - fog_blue, + case 2: //TEST + Fog_Update(r_refdef.fog_start, + r_refdef.fog_end, + r_refdef.fog_red, + r_refdef.fog_green, + r_refdef.fog_blue, + atof(Cmd_Argv(1))); + break; + case 3: + Fog_Update(atof(Cmd_Argv(1)), + atof(Cmd_Argv(2)), + r_refdef.fog_red, + r_refdef.fog_green, + r_refdef.fog_blue, 0.0); break; - case 3: //TEST - Fog_Update(max(0.0, atof(Cmd_Argv(1))), - fog_red, - fog_green, - fog_blue, - atof(Cmd_Argv(2))); - break; case 4: - Fog_Update(fog_density_gl, - CLAMP(0.0, atof(Cmd_Argv(1)), 1.0), - CLAMP(0.0, atof(Cmd_Argv(2)), 1.0), - CLAMP(0.0, atof(Cmd_Argv(3)), 1.0), + Fog_Update(r_refdef.fog_start, + r_refdef.fog_end, + CLAMP(0.0, atof(Cmd_Argv(1)), 100.0), + CLAMP(0.0, atof(Cmd_Argv(2)), 100.0), + CLAMP(0.0, atof(Cmd_Argv(3)), 100.0), 0.0); break; - case 5: - Fog_Update(max(0.0, atof(Cmd_Argv(1))), - CLAMP(0.0, atof(Cmd_Argv(2)), 1.0), - CLAMP(0.0, atof(Cmd_Argv(3)), 1.0), - CLAMP(0.0, atof(Cmd_Argv(4)), 1.0), + case 5: //TEST + Fog_Update(r_refdef.fog_start, + r_refdef.fog_end, + CLAMP(0.0, atof(Cmd_Argv(1)), 100.0), + CLAMP(0.0, atof(Cmd_Argv(2)), 100.0), + CLAMP(0.0, atof(Cmd_Argv(3)), 100.0), + atof(Cmd_Argv(4))); + break; + case 6: + Fog_Update(atof(Cmd_Argv(1)), + atof(Cmd_Argv(2)), + CLAMP(0.0, atof(Cmd_Argv(3)), 100.0), + CLAMP(0.0, atof(Cmd_Argv(4)), 100.0), + CLAMP(0.0, atof(Cmd_Argv(5)), 100.0), 0.0); break; - case 6: //TEST - Fog_Update(max(0.0, atof(Cmd_Argv(1))), - CLAMP(0.0, atof(Cmd_Argv(2)), 1.0), - CLAMP(0.0, atof(Cmd_Argv(3)), 1.0), - CLAMP(0.0, atof(Cmd_Argv(4)), 1.0), - atof(Cmd_Argv(5))); + case 7: + Fog_Update(atof(Cmd_Argv(1)), + atof(Cmd_Argv(2)), + CLAMP(0.0, atof(Cmd_Argv(3)), 100.0), + CLAMP(0.0, atof(Cmd_Argv(4)), 100.0), + CLAMP(0.0, atof(Cmd_Argv(5)), 100.0), + atof(Cmd_Argv(6))); break; } } @@ -170,18 +185,23 @@ called at map load void Fog_ParseWorldspawn (void) { char key[128], value[4096]; - const char *data; + char *data; //initially no fog - fog_density_gl = DEFAULT_DENSITY; - fog_red = DEFAULT_GRAY; - fog_green = DEFAULT_GRAY; - fog_blue = DEFAULT_GRAY; + r_refdef.fog_start = 0; + old_start = 0; - old_density = DEFAULT_DENSITY; - old_red = DEFAULT_GRAY; - old_green = DEFAULT_GRAY; - old_blue = DEFAULT_GRAY; + r_refdef.fog_end = -1; + old_end = -1; + + r_refdef.fog_red = 0.0; + old_red = 0.0; + + r_refdef.fog_green = 0.0; + old_green = 0.0; + + r_refdef.fog_blue = 0.0; + old_blue = 0.0; fade_time = 0.0; fade_done = 0.0; @@ -211,68 +231,11 @@ void Fog_ParseWorldspawn (void) if (!strcmp("fog", key)) { - sscanf(value, "%f %f %f %f %f", &fog_start, &fog_end, &fog_red, &fog_green, &fog_blue); + sscanf(value, "%f %f %f %f %f", &r_refdef.fog_start, &r_refdef.fog_end, &r_refdef.fog_red, &r_refdef.fog_green, &r_refdef.fog_blue); } - - fog_density_gl = ((fog_end - fog_start))/6000; } } -/* -============= -Fog_GetColor -calculates fog color for this frame, taking into account fade times -============= -*/ -float *Fog_GetColor (void) -{ - static float c[4] = {0.3f, 0.3f, 0.3f, 1.0f}; -#ifndef VITA - float f; - int i; - - if (fade_done > cl.time) - { - f = (fade_done - cl.time) / fade_time; - c[0] = f * old_red + (1.0 - f) * fog_red; - c[1] = f * old_green + (1.0 - f) * fog_green; - c[2] = f * old_blue + (1.0 - f) * fog_blue; - c[3] = 1.0; - } - else - { - c[0] = fog_red; - c[1] = fog_green; - c[2] = fog_blue; - c[3] = 1.0; - } - - //find closest 24-bit RGB value, so solid-colored sky can match the fog perfectly - for (i=0;i<3;i++) - c[i] = (float)(Q_rint(c[i] * 255)) / 255.0f; -#endif - return c; -} - -/* -============= -Fog_GetDensity -returns current density of fog -============= -*/ -float Fog_GetDensity (void) -{ - float f; - - if (fade_done > cl.time) - { - f = (fade_done - cl.time) / fade_time; - return f * old_density + (1.0 - f) * fog_density_gl; - } - else - return fog_density_gl; -} - /* ============= Fog_SetupFrame @@ -281,8 +244,77 @@ called at the beginning of each frame */ void Fog_SetupFrame (void) { - glFogfv(GL_FOG_COLOR, Fog_GetColor()); - glFogf(GL_FOG_DENSITY, Fog_GetDensity() / 64.0); + float c[4]; + float f, s, e; + + if (fade_done > cl.time) + { + f = (fade_done - cl.time) / fade_time; + s = f * old_start + (1.0 - f) * r_refdef.fog_start; + e = f * old_end + (1.0 - f) * r_refdef.fog_end; + c[0] = f * old_red + (1.0 - f) * r_refdef.fog_red; + c[1] = f * old_green + (1.0 - f) * r_refdef.fog_green; + c[2] = f * old_blue + (1.0 - f) * r_refdef.fog_blue; + c[3] = 1.0; + //c[3] = r_skyfog.value; + } + else + { + s = r_refdef.fog_start; + e = r_refdef.fog_end; + c[0] = r_refdef.fog_red; + c[1] = r_refdef.fog_green; + c[2] = r_refdef.fog_blue; + c[3] = 1.0; + //c[3] = r_skyfog.value; + } + + if(e == 0) + e = -1; + + glFogf(GL_FOG_DENSITY, 0.6); + glFogf(GL_FOG_COLOR, *c); + + if(s == 0 || e < 0) + glDisable(GL_FOG); +} + +/* +============= +Fog_GetStart +returns current start of fog +============= +*/ +float Fog_GetStart (void) +{ + float f; + + if (fade_done > cl.time) + { + f = (fade_done - cl.time) / fade_time; + return f * old_start + (1.0 - f) * r_refdef.fog_start; + } + else + return r_refdef.fog_start; +} + +/* +============= +Fog_GetEnd +returns current end of fog +============= +*/ +float Fog_GetEnd (void) +{ + float f; + + if (fade_done > cl.time) + { + f = (fade_done - cl.time) / fade_time; + return f * old_start + (1.0 - f) * r_refdef.fog_end; + } + else + return r_refdef.fog_end; } /* @@ -293,7 +325,7 @@ called before drawing stuff that should be fogged */ void Fog_EnableGFog (void) { - if (Fog_GetDensity() > 0) + if (!Fog_GetStart() == 0 || (!Fog_GetEnd()) <= 0) glEnable(GL_FOG); } @@ -305,36 +337,10 @@ called after drawing stuff that should be fogged */ void Fog_DisableGFog (void) { - if (Fog_GetDensity() > 0) + if (!Fog_GetStart() == 0 || (!Fog_GetEnd()) <= 0) glDisable(GL_FOG); } -/* -============= -Fog_StartAdditive -called before drawing stuff that is additive blended -- sets fog color to black -============= -*/ -void Fog_StartAdditive (void) -{ - vec3_t color = {0,0,0}; - - if (Fog_GetDensity() > 0) - glFogfv(GL_FOG_COLOR, color); -} - -/* -============= -Fog_StopAdditive -called after drawing stuff that is additive blended -- restores fog color -============= -*/ -void Fog_StopAdditive (void) -{ - if (Fog_GetDensity() > 0) - glFogfv(GL_FOG_COLOR, Fog_GetColor()); -} - //============================================================================== // // INIT @@ -350,6 +356,7 @@ called whenever a map is loaded void Fog_NewMap (void) { Fog_ParseWorldspawn (); //for global fog +// Fog_MarkModels (); //for volumetric fog } /* @@ -363,10 +370,12 @@ void Fog_Init (void) Cmd_AddCommand ("fog",Fog_FogCommand_f); //set up global fog - fog_density_gl = DEFAULT_DENSITY; - fog_red = DEFAULT_GRAY; - fog_green = DEFAULT_GRAY; - fog_blue = DEFAULT_GRAY; + r_refdef.fog_start = 0; + r_refdef.fog_end = -1; + r_refdef.fog_red = 0.5; + r_refdef.fog_green = 0.5; + r_refdef.fog_blue = 0.5; + fade_time = 1; Fog_SetupState (); } diff --git a/source/render.h b/source/render.h index 07b8f2b..18269a1 100644 --- a/source/render.h +++ b/source/render.h @@ -132,6 +132,12 @@ typedef struct float fov_x, fov_y; int ambientlight; + + float fog_start; + float fog_end; + float fog_red; + float fog_green; + float fog_blue; } refdef_t;