diff --git a/include/QF/GL/qf_funcs_list.h b/include/QF/GL/qf_funcs_list.h index dad3cd7c6..72dba294a 100644 --- a/include/QF/GL/qf_funcs_list.h +++ b/include/QF/GL/qf_funcs_list.h @@ -150,9 +150,9 @@ QFGL_DONT_NEED (void, glEvalPoint2, (GLint i, GLint j)) QFGL_DONT_NEED (void, glFeedbackBuffer, (GLsizei size, GLenum type, GLfloat * buffer)) QFGL_NEED (void, glFinish, (void)) QFGL_NEED (void, glFlush, (void)) -QFGL_DONT_NEED (void, glFogf, (GLenum pname, GLfloat param)) -QFGL_DONT_NEED (void, glFogfv, (GLenum pname, const GLfloat * params)) -QFGL_DONT_NEED (void, glFogi, (GLenum pname, GLint param)) +QFGL_NEED (void, glFogf, (GLenum pname, GLfloat param)) +QFGL_NEED (void, glFogfv, (GLenum pname, const GLfloat * params)) +QFGL_NEED (void, glFogi, (GLenum pname, GLint param)) QFGL_DONT_NEED (void, glFogiv, (GLenum pname, const GLint * params)) QFGL_DONT_NEED (void, glFrontFace, (GLenum mode)) QFGL_NEED (void, glFrustum, (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val)) diff --git a/include/QF/render.h b/include/QF/render.h index 00d0db57e..5fa1e2132 100644 --- a/include/QF/render.h +++ b/include/QF/render.h @@ -179,6 +179,19 @@ void R_NewMap (model_t *worldmodel, struct model_s **models, int num_models); void R_PushDlights (const vec3_t entorigin); void R_DrawWaterSurfaces (void); +void Fog_Update (float density, float red, float green, float blue, + float time); +struct plitem_s; +void Fog_ParseWorldspawn (struct plitem_s *worldspawn); +float *Fog_GetColor (void); +float Fog_GetDensity (void); +void Fog_SetupFrame (void); +void Fog_EnableGFog (void); +void Fog_DisableGFog (void); +void Fog_StartAdditive (void); +void Fog_StopAdditive (void); +void Fog_Init (void); + // Surface cache related ========== extern int reinit_surfcache; // if 1, surface cache is currently empty extern qboolean r_cache_thrash; // set if thrashing the surface cache diff --git a/libs/video/renderer/gl/Makefile.am b/libs/video/renderer/gl/Makefile.am index ae1fa77f2..360bf8f9e 100644 --- a/libs/video/renderer/gl/Makefile.am +++ b/libs/video/renderer/gl/Makefile.am @@ -11,7 +11,7 @@ endif gl_src = \ gl_draw.c gl_dyn_lights.c gl_dyn_part.c gl_dyn_textures.c \ - gl_graph.c gl_lightmap.c gl_mod_alias.c gl_mod_sprite.c \ + gl_fog.c gl_graph.c gl_lightmap.c gl_mod_alias.c gl_mod_sprite.c \ gl_rmain.c gl_rmisc.c gl_rsurf.c gl_screen.c gl_skin.c gl_sky.c \ gl_sky_clip.c gl_textures.c gl_warp.c noisetextures.c diff --git a/libs/video/renderer/gl/gl_fog.c b/libs/video/renderer/gl/gl_fog.c new file mode 100644 index 000000000..58592687f --- /dev/null +++ b/libs/video/renderer/gl/gl_fog.c @@ -0,0 +1,342 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//gl_fog.c -- global and volumetric fog + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +static __attribute__ ((used)) const char rcsid[] = "$Id$"; + +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif + +#include "QF/cmd.h" +#include "QF/qfplist.h" +#include "QF/render.h" +#include "QF/sys.h" + +#include "QF/GL/defines.h" +#include "QF/GL/funcs.h" + +#include "compat.h" +#include "r_shared.h" + +//============================================================================== +// +// GLOBAL FOG +// +//============================================================================== + +static float fog_density; +static float fog_red; +static float fog_green; +static float fog_blue; + +static float old_density; +static float old_red; +static float old_green; +static float old_blue; + +static float fade_time; //duration of fade +static float fade_done; //time when fade will be done + +/* + Fog_Update + + update internal variables +*/ +void +Fog_Update (float density, float red, float green, float blue, float time) +{ + //save previous settings for fade + if (time > 0) { + //check for a fade in progress + if (fade_done > r_realtime) { + float f; + + f = (fade_done - r_realtime) / fade_time; + old_density = f * old_density + (1.0 - f) * fog_density; + 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; + } else { + old_density = fog_density; + old_red = fog_red; + old_green = fog_green; + old_blue = fog_blue; + } + } + + fog_density = density; + fog_red = red; + fog_green = green; + fog_blue = blue; + fade_time = time; + fade_done = r_realtime + time; +} + +/* + Fog_FogCommand_f + + handle the 'fog' console command +*/ +static void +Fog_FogCommand_f (void) +{ + switch (Cmd_Argc ()) { + default: + case 1: + Sys_Printf ("usage:\n"); + Sys_Printf (" fog \n"); + Sys_Printf (" fog \n"); + Sys_Printf (" fog \n"); + Sys_Printf ("current values:\n"); + Sys_Printf (" \"density\" is \"%f\"\n", fog_density); + Sys_Printf (" \"red\" is \"%f\"\n", fog_red); + Sys_Printf (" \"green\" is \"%f\"\n", fog_green); + Sys_Printf (" \"blue\" is \"%f\"\n", fog_blue); + break; + case 2: + Fog_Update (max (0.0, atof (Cmd_Argv (1))), + fog_red, fog_green, 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, + bound (0.0, atof (Cmd_Argv (1)), 1.0), + bound (0.0, atof (Cmd_Argv (2)), 1.0), + bound (0.0, atof (Cmd_Argv (3)), 1.0), + 0.0); + break; + case 5: + Fog_Update (max (0.0, atof (Cmd_Argv (1))), + bound (0.0, atof (Cmd_Argv (2)), 1.0), + bound (0.0, atof (Cmd_Argv (3)), 1.0), + bound (0.0, atof (Cmd_Argv (4)), 1.0), + 0.0); + break; + case 6: //TEST + Fog_Update (max (0.0, atof (Cmd_Argv (1))), + bound (0.0, atof (Cmd_Argv (2)), 1.0), + bound (0.0, atof (Cmd_Argv (3)), 1.0), + bound (0.0, atof (Cmd_Argv (4)), 1.0), + atof (Cmd_Argv (5))); + break; + } +} + +/* + Fog_ParseWorldspawn + + called at map load +*/ +void +Fog_ParseWorldspawn (plitem_t *worldspawn) +{ + plitem_t *fog; + const char *value; + + //initially no fog + fog_density = 0.0; + old_density = 0.0; + fade_time = 0.0; + fade_done = 0.0; + + if (!worldspawn) + return; // error + if ((fog = PL_ObjectForKey (worldspawn, "fog")) + && (value = PL_String (fog))) { + sscanf (value, "%f %f %f %f", &fog_density, + &fog_red, &fog_green, &fog_blue); + } +} + +/* + Fog_GetColor + + calculates fog color for this frame, taking into account fade times +*/ +float * +Fog_GetColor (void) +{ + static float c[4]; + float f; + int i; + + if (fade_done > r_realtime) { + f = (fade_done - r_realtime) / 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) (rint (c[i] * 255)) / 255.0f; + + return c; +} + +/* + Fog_GetDensity + + returns current density of fog +*/ +float +Fog_GetDensity (void) +{ + float f; + + if (fade_done > r_realtime) { + f = (fade_done - r_realtime) / fade_time; + return f * old_density + (1.0 - f) * fog_density; + } else { + return fog_density; + } +} + +/* + Fog_SetupFrame + + called at the beginning of each frame +*/ +void +Fog_SetupFrame (void) +{ + qfglFogfv (GL_FOG_COLOR, Fog_GetColor ()); + qfglFogf (GL_FOG_DENSITY, Fog_GetDensity () / 64.0); +} + +/* + Fog_EnableGFog + + called before drawing stuff that should be fogged +*/ +void +Fog_EnableGFog (void) +{ + if (Fog_GetDensity () > 0) + qfglEnable (GL_FOG); +} + +/* + Fog_DisableGFog + + called after drawing stuff that should be fogged +*/ +void +Fog_DisableGFog (void) +{ + if (Fog_GetDensity () > 0) + qfglDisable (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) + qfglFogfv (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) + qfglFogfv (GL_FOG_COLOR, Fog_GetColor ()); +} + +//============================================================================== +// +// VOLUMETRIC FOG +// +//============================================================================== + +//cvar_t r_vfog = {"r_vfog", "1"}; + +//void Fog_DrawVFog (void) {} +//void Fog_MarkModels (void) {} + +//============================================================================== +// +// INIT +// +//============================================================================== + +/* + Fog_NewMap + + called whenever a map is loaded +*/ +#if 0 +void +Fog_NewMap (void) +{ + Fog_ParseWorldspawn (); //for global fog + Fog_MarkModels (); //for volumetric fog +} +#endif + +/* + Fog_Init + + called when quake initializes +*/ +void +Fog_Init (void) +{ + Cmd_AddCommand ("fog", Fog_FogCommand_f, ""); + + //Cvar_RegisterVariable (&r_vfog, NULL); + + //set up global fog + fog_density = 0.0; + fog_red = 0.3; + fog_green = 0.3; + fog_blue = 0.3; + + qfglFogi (GL_FOG_MODE, GL_EXP2); +} diff --git a/libs/video/renderer/sw/Makefile.am b/libs/video/renderer/sw/Makefile.am index 4d861a0a0..fa9341c0c 100644 --- a/libs/video/renderer/sw/Makefile.am +++ b/libs/video/renderer/sw/Makefile.am @@ -24,7 +24,7 @@ asm_src= \ sw_src= \ d_edge.c d_fill.c d_init.c d_modech.c d_part.c d_polyse.c d_scan.c \ d_sky.c d_sprite.c d_surf.c d_vars.c d_zpoint.c draw.c fpu.c nonintel.c \ - screen.c sw_graph.c sw_raclip.c sw_ralias.c sw_rbsp.c sw_rdraw.c \ + screen.c sw_fog.c sw_graph.c sw_raclip.c sw_ralias.c sw_rbsp.c sw_rdraw.c \ sw_redge.c sw_rmain.c sw_rmisc.c sw_rpart.c sw_rsky.c sw_rsprite.c \ sw_rsurf.c sw_skin.c diff --git a/libs/video/renderer/sw/sw_fog.c b/libs/video/renderer/sw/sw_fog.c new file mode 100644 index 000000000..bfe7171ec --- /dev/null +++ b/libs/video/renderer/sw/sw_fog.c @@ -0,0 +1,43 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//sw_fog.c -- global and volumetric fog + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +static __attribute__ ((used)) const char rcsid[] = "$Id$"; + +#include "QF/render.h" + +void +Fog_Update (float density, float red, float green, float blue, float time) +{ +} + +void +Fog_ParseWorldspawn (struct plitem_s *worldspawn) +{ +} + +void +Fog_Init (void) +{ +} diff --git a/libs/video/renderer/sw32/Makefile.am b/libs/video/renderer/sw32/Makefile.am index 7ebbaff69..6e191d3c5 100644 --- a/libs/video/renderer/sw32/Makefile.am +++ b/libs/video/renderer/sw32/Makefile.am @@ -12,9 +12,9 @@ endif sw32_src= \ d_edge.c d_fill.c d_init.c d_modech.c d_part.c d_polyse.c d_scan.c \ d_sky.c d_sprite.c d_surf.c d_vars.c d_zpoint.c draw.c screen.c \ - sw32_graph.c sw32_raclip.c sw32_ralias.c sw32_rbsp.c sw32_rdraw.c \ - sw32_redge.c sw32_rmain.c sw32_rmisc.c sw32_rpart.c sw32_rsky.c \ - sw32_rsprite.c sw32_rsurf.c sw32_skin.c + sw32_fog.c sw32_graph.c sw32_raclip.c sw32_ralias.c sw32_rbsp.c \ + sw32_rdraw.c sw32_redge.c sw32_rmain.c sw32_rmisc.c sw32_rpart.c \ + sw32_rsky.c sw32_rsprite.c sw32_rsurf.c sw32_skin.c libsw32_la_SOURCES= $(sw32_src) diff --git a/libs/video/renderer/sw32/sw32_fog.c b/libs/video/renderer/sw32/sw32_fog.c new file mode 100644 index 000000000..e1f96161b --- /dev/null +++ b/libs/video/renderer/sw32/sw32_fog.c @@ -0,0 +1,43 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//sw32_fog.c -- global and volumetric fog + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +static __attribute__ ((used)) const char rcsid[] = "$Id$"; + +#include "QF/render.h" + +void +Fog_Update (float density, float red, float green, float blue, float time) +{ +} + +void +Fog_ParseWorldspawn (struct plitem_s *worldspawn) +{ +} + +void +Fog_Init (void) +{ +} diff --git a/nq/source/cl_parse.c b/nq/source/cl_parse.c index c8f1eb7d4..69baecaf3 100644 --- a/nq/source/cl_parse.c +++ b/nq/source/cl_parse.c @@ -308,6 +308,7 @@ CL_NewMap (const char *mapname) if (cl.edicts) { cl.worldspawn = PL_ObjectAtIndex (cl.edicts, 0); CL_LoadSky (); + Fog_ParseWorldspawn (cl.worldspawn); } } @@ -1117,7 +1118,7 @@ CL_ParseServerMessage (void) Cmd_ExecuteString ("bf", src_command); break; case svc_fog: - { //FIXME implement + { float density, red, green, blue, time; density = MSG_ReadByte (net_message) / 255.0; red = MSG_ReadByte (net_message) / 255.0; @@ -1125,6 +1126,7 @@ CL_ParseServerMessage (void) blue = MSG_ReadByte (net_message) / 255.0; time = MSG_ReadShort (net_message) / 100.0; time = max (0.0, time); + Fog_Update (density, red, green, blue, time); } break; case svc_spawnbaseline2: