From 731236ee072de29f0fd56c7aff43aa4b53a9d8ae Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 29 Jan 2012 10:27:28 +0900 Subject: [PATCH] Implement global fog. Sprites and particles don't seem to be getting fogged correctly, but bsp and alias models are working. --- libs/video/renderer/glsl/Makefile.am | 4 +- libs/video/renderer/glsl/glsl_alias.c | 9 + libs/video/renderer/glsl/glsl_bsp.c | 31 +++ libs/video/renderer/glsl/glsl_fog.c | 247 ++++++++++++++++++++++ libs/video/renderer/glsl/glsl_main.c | 11 +- libs/video/renderer/glsl/glsl_particles.c | 16 ++ libs/video/renderer/glsl/glsl_sprite.c | 8 + libs/video/renderer/glsl/quakebsp.frag | 21 +- libs/video/renderer/glsl/quakemdl.frag | 19 +- libs/video/renderer/glsl/quakepar.frag | 19 +- libs/video/renderer/glsl/quakepnt.frag | 19 +- libs/video/renderer/glsl/quakeskb.frag | 19 +- libs/video/renderer/glsl/quakeski.frag | 19 +- libs/video/renderer/glsl/quakespr.frag | 20 +- libs/video/renderer/glsl/quaketrb.frag | 19 +- 15 files changed, 461 insertions(+), 20 deletions(-) create mode 100644 libs/video/renderer/glsl/glsl_fog.c diff --git a/libs/video/renderer/glsl/Makefile.am b/libs/video/renderer/glsl/Makefile.am index 6c89c3272..b352e8877 100644 --- a/libs/video/renderer/glsl/Makefile.am +++ b/libs/video/renderer/glsl/Makefile.am @@ -14,8 +14,8 @@ shader_gen= \ quakesky.vc quakespr.fc quakespr.vc quaketrb.fc quaketxt.vc glsl_src = \ - glsl_alias.c glsl_bsp.c glsl_draw.c glsl_lightmap.c glsl_main.c \ - glsl_particles.c glsl_screen.c glsl_sprite.c glsl_textures.c + glsl_alias.c glsl_bsp.c glsl_draw.c glsl_fog.c glsl_lightmap.c \ + glsl_main.c glsl_particles.c glsl_screen.c glsl_sprite.c glsl_textures.c if BUILD_GLSL noinst_LTLIBRARIES= libglsl.la diff --git a/libs/video/renderer/glsl/glsl_alias.c b/libs/video/renderer/glsl/glsl_alias.c index b054892b4..c91e74d96 100644 --- a/libs/video/renderer/glsl/glsl_alias.c +++ b/libs/video/renderer/glsl/glsl_alias.c @@ -79,6 +79,7 @@ static struct { shaderparam_t ambient; shaderparam_t shadelight; shaderparam_t lightvec; + shaderparam_t fog; } quake_mdl = { 0, {"mvp_mat", 1}, @@ -98,6 +99,7 @@ static struct { {"ambient", 1}, {"shadelight", 1}, {"lightvec", 1}, + {"fog", 1}, }; static mat4_t alias_vp; @@ -129,6 +131,7 @@ R_InitAlias (void) GL_ResolveShaderParam (quake_mdl.program, &quake_mdl.ambient); GL_ResolveShaderParam (quake_mdl.program, &quake_mdl.shadelight); GL_ResolveShaderParam (quake_mdl.program, &quake_mdl.lightvec); + GL_ResolveShaderParam (quake_mdl.program, &quake_mdl.fog); } static void @@ -288,6 +291,8 @@ R_DrawAlias (void) void R_AliasBegin (void) { + quat_t fog; + // pre-multiply the view and projection matricies Mat4Mult (glsl_projection, glsl_view, alias_vp); @@ -301,6 +306,10 @@ R_AliasBegin (void) qfglDisableVertexAttribArray (quake_mdl.colora.location); qfglDisableVertexAttribArray (quake_mdl.colorb.location); + VectorCopy (Fog_GetColor (), fog); + fog[3] = Fog_GetDensity () / 64.0; + qfglUniform4fv (quake_mdl.fog.location, 1, fog); + qfglUniform1i (quake_mdl.colormap.location, 1); qfglActiveTexture (GL_TEXTURE0 + 1); qfglEnable (GL_TEXTURE_2D); diff --git a/libs/video/renderer/glsl/glsl_bsp.c b/libs/video/renderer/glsl/glsl_bsp.c index 8d9c22baa..dfc8a0543 100644 --- a/libs/video/renderer/glsl/glsl_bsp.c +++ b/libs/video/renderer/glsl/glsl_bsp.c @@ -133,6 +133,7 @@ static struct { shaderparam_t texture; shaderparam_t lightmap; shaderparam_t color; + shaderparam_t fog; } quake_bsp = { 0, {"mvp_mat", 1}, @@ -142,6 +143,7 @@ static struct { {"texture", 1}, {"lightmap", 1}, {"vcolor", 0}, + {"fog", 1}, }; static struct { @@ -153,6 +155,7 @@ static struct { shaderparam_t texture; shaderparam_t realtime; shaderparam_t color; + shaderparam_t fog; } quake_turb = { 0, {"mvp_mat", 1}, @@ -162,6 +165,7 @@ static struct { {"texture", 1}, {"realtime", 1}, {"vcolor", 0}, + {"fog", 1}, }; static struct { @@ -173,6 +177,7 @@ static struct { shaderparam_t solid; shaderparam_t trans; shaderparam_t realtime; + shaderparam_t fog; } quake_skyid = { 0, {"mvp_mat", 1}, @@ -182,6 +187,7 @@ static struct { {"solid", 1}, {"trans", 1}, {"realtime", 1}, + {"fog", 1}, }; static struct { @@ -190,18 +196,21 @@ static struct { shaderparam_t sky_matrix; shaderparam_t vertex; shaderparam_t sky; + shaderparam_t fog; } quake_skybox = { 0, {"mvp_mat", 1}, {"sky_mat", 1}, {"vertex", 0}, {"sky", 1}, + {"fog", 1}, }; static struct { shaderparam_t *mvp_matrix; shaderparam_t *sky_matrix; shaderparam_t *vertex; + shaderparam_t *fog; } sky_params; #define CHAIN_SURF_F2B(surf,chain) \ @@ -805,6 +814,8 @@ static void bsp_begin (void) { static quat_t color = { 1, 1, 1, 1 }; + quat_t fog; + Mat4Mult (glsl_projection, glsl_view, bsp_vp); qfglUseProgram (quake_bsp.program); @@ -814,6 +825,10 @@ bsp_begin (void) qfglVertexAttrib4fv (quake_bsp.color.location, color); + VectorCopy (Fog_GetColor (), fog); + fog[3] = Fog_GetDensity () / 64.0; + qfglUniform4fv (quake_bsp.fog.location, 1, fog); + qfglUniform1i (quake_bsp.colormap.location, 2); qfglActiveTexture (GL_TEXTURE0 + 2); qfglEnable (GL_TEXTURE_2D); @@ -851,6 +866,7 @@ static void turb_begin (void) { static quat_t color = { 1, 1, 1, 1 }; + quat_t fog; Mat4Mult (glsl_projection, glsl_view, bsp_vp); @@ -862,6 +878,10 @@ turb_begin (void) color[3] = bound (0, r_wateralpha->value, 1); qfglVertexAttrib4fv (quake_turb.color.location, color); + VectorCopy (Fog_GetColor (), fog); + fog[3] = Fog_GetDensity () / 64.0; + qfglUniform4fv (quake_turb.fog.location, 1, fog); + qfglUniform1i (quake_turb.palette.location, 1); qfglActiveTexture (GL_TEXTURE0 + 1); qfglEnable (GL_TEXTURE_2D); @@ -915,6 +935,7 @@ static void sky_begin (void) { mat4_t mat; + quat_t fog; Mat4Mult (glsl_projection, glsl_view, bsp_vp); @@ -922,6 +943,7 @@ sky_begin (void) sky_params.mvp_matrix = &quake_skybox.mvp_matrix; sky_params.vertex = &quake_skybox.vertex; sky_params.sky_matrix = &quake_skybox.sky_matrix; + sky_params.fog = &quake_skybox.fog; qfglUseProgram (quake_skybox.program); qfglEnableVertexAttribArray (quake_skybox.vertex.location); @@ -934,6 +956,7 @@ sky_begin (void) sky_params.mvp_matrix = &quake_skyid.mvp_matrix; sky_params.sky_matrix = &quake_skyid.sky_matrix; sky_params.vertex = &quake_skyid.vertex; + sky_params.fog = &quake_skyid.fog; qfglUseProgram (quake_skyid.program); qfglEnableVertexAttribArray (quake_skyid.vertex.location); @@ -954,6 +977,10 @@ sky_begin (void) qfglEnable (GL_TEXTURE_2D); } + VectorCopy (Fog_GetColor (), fog); + fog[3] = Fog_GetDensity () / 64.0; + qfglUniform4fv (sky_params.fog->location, 1, fog); + spin (mat); qfglUniformMatrix4fv (sky_params.sky_matrix->location, 1, false, mat); @@ -1183,6 +1210,7 @@ R_InitBsp (void) GL_ResolveShaderParam (quake_bsp.program, &quake_bsp.texture); GL_ResolveShaderParam (quake_bsp.program, &quake_bsp.lightmap); GL_ResolveShaderParam (quake_bsp.program, &quake_bsp.color); + GL_ResolveShaderParam (quake_bsp.program, &quake_bsp.fog); frag = GL_CompileShader ("quaketrb.frag", quaketurb_frag, GL_FRAGMENT_SHADER); @@ -1194,6 +1222,7 @@ R_InitBsp (void) GL_ResolveShaderParam (quake_turb.program, &quake_turb.texture); GL_ResolveShaderParam (quake_turb.program, &quake_turb.realtime); GL_ResolveShaderParam (quake_turb.program, &quake_turb.color); + GL_ResolveShaderParam (quake_turb.program, &quake_turb.fog); vert = GL_CompileShader ("quakesky.vert", quakesky_vert, GL_VERTEX_SHADER); frag = GL_CompileShader ("quakeski.frag", quakeskyid_frag, @@ -1206,6 +1235,7 @@ R_InitBsp (void) GL_ResolveShaderParam (quake_skyid.program, &quake_skyid.solid); GL_ResolveShaderParam (quake_skyid.program, &quake_skyid.trans); GL_ResolveShaderParam (quake_skyid.program, &quake_skyid.realtime); + GL_ResolveShaderParam (quake_skyid.program, &quake_skyid.fog); frag = GL_CompileShader ("quakeskb.frag", quakeskybox_frag, GL_FRAGMENT_SHADER); @@ -1214,6 +1244,7 @@ R_InitBsp (void) GL_ResolveShaderParam (quake_skybox.program, &quake_skybox.sky_matrix); GL_ResolveShaderParam (quake_skybox.program, &quake_skybox.vertex); GL_ResolveShaderParam (quake_skybox.program, &quake_skybox.sky); + GL_ResolveShaderParam (quake_skybox.program, &quake_skybox.fog); } VISIBLE void diff --git a/libs/video/renderer/glsl/glsl_fog.c b/libs/video/renderer/glsl/glsl_fog.c new file mode 100644 index 000000000..ab072d261 --- /dev/null +++ b/libs/video/renderer/glsl/glsl_fog.c @@ -0,0 +1,247 @@ +/* +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/GLSL/defines.h" +#include "QF/GLSL/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_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; +} diff --git a/libs/video/renderer/glsl/glsl_main.c b/libs/video/renderer/glsl/glsl_main.c index 645718856..4c116d5f3 100644 --- a/libs/video/renderer/glsl/glsl_main.c +++ b/libs/video/renderer/glsl/glsl_main.c @@ -260,6 +260,7 @@ R_Init (void) R_InitAlias (); R_InitSprites (); R_InitParticles (); + Fog_Init (); } VISIBLE void @@ -280,16 +281,6 @@ R_NewMap (model_t *worldmodel, struct model_s **models, int num_models) R_BuildDisplayLists (models, num_models); } -VISIBLE void -Fog_Update (float density, float red, float green, float blue, float time) -{ -} - -VISIBLE void -Fog_ParseWorldspawn (struct plitem_s *worldspawn) -{ -} - VISIBLE void R_LineGraph (int x, int y, int *h_vals, int count) { diff --git a/libs/video/renderer/glsl/glsl_particles.c b/libs/video/renderer/glsl/glsl_particles.c index 6df447370..b7f69eb8e 100644 --- a/libs/video/renderer/glsl/glsl_particles.c +++ b/libs/video/renderer/glsl/glsl_particles.c @@ -99,12 +99,14 @@ static struct { shaderparam_t vertex; shaderparam_t palette; shaderparam_t color; + shaderparam_t fog; } quake_point = { 0, {"mvp_mat", 1}, {"vertex", 0}, {"palette", 1}, {"vcolor", 0}, + {"fog", 0}, }; static struct { @@ -114,6 +116,7 @@ static struct { shaderparam_t vertex; shaderparam_t color; shaderparam_t texture; + shaderparam_t fog; } quake_part = { 0, {"mvp_mat", 1}, @@ -121,6 +124,7 @@ static struct { {"vertex", 0}, {"vcolor", 0}, {"texture", 1}, + {"fog", 0}, }; inline static void @@ -225,6 +229,7 @@ R_InitParticles (void) GL_ResolveShaderParam (quake_point.program, &quake_point.vertex); GL_ResolveShaderParam (quake_point.program, &quake_point.palette); GL_ResolveShaderParam (quake_point.program, &quake_point.color); + GL_ResolveShaderParam (quake_point.program, &quake_point.fog); vert = GL_CompileShader ("quakepar.vert", quakepart_vert, GL_VERTEX_SHADER); @@ -236,6 +241,7 @@ R_InitParticles (void) GL_ResolveShaderParam (quake_part.program, &quake_part.vertex); GL_ResolveShaderParam (quake_part.program, &quake_part.color); GL_ResolveShaderParam (quake_part.program, &quake_part.texture); + GL_ResolveShaderParam (quake_part.program, &quake_part.fog); memset (data, 0, sizeof (data)); qfglGenTextures (1, &part_tex); @@ -1534,6 +1540,7 @@ draw_qf_particles (void) vec3_t up_scale, right_scale, up_right_scale, down_right_scale; partvert_t *VA; mat4_t vp_mat; + quat_t fog; Mat4Mult (glsl_projection, glsl_view, vp_mat); @@ -1543,6 +1550,10 @@ draw_qf_particles (void) qfglEnableVertexAttribArray (quake_part.color.location); qfglEnableVertexAttribArray (quake_part.st.location); + VectorCopy (Fog_GetColor (), fog); + fog[3] = Fog_GetDensity () / 64.0; + qfglUniform4fv (quake_part.fog.location, 1, fog); + qfglUniformMatrix4fv (quake_part.mvp_matrix.location, 1, false, vp_mat); qfglUniform1i (quake_part.texture.location, 0); @@ -1673,6 +1684,7 @@ draw_id_particles (void) particle_t *part; partvert_t *VA; mat4_t vp_mat; + quat_t fog; Mat4Mult (glsl_projection, glsl_view, vp_mat); @@ -1684,6 +1696,10 @@ draw_id_particles (void) qfglUniformMatrix4fv (quake_point.mvp_matrix.location, 1, false, vp_mat); + VectorCopy (Fog_GetColor (), fog); + fog[3] = Fog_GetDensity () / 64.0; + qfglUniform4fv (quake_point.fog.location, 1, fog); + qfglUniform1i (quake_point.palette.location, 0); qfglActiveTexture (GL_TEXTURE0 + 0); qfglEnable (GL_TEXTURE_2D); diff --git a/libs/video/renderer/glsl/glsl_sprite.c b/libs/video/renderer/glsl/glsl_sprite.c index d5ebaec65..914fd1736 100644 --- a/libs/video/renderer/glsl/glsl_sprite.c +++ b/libs/video/renderer/glsl/glsl_sprite.c @@ -76,6 +76,7 @@ static struct { shaderparam_t colora; shaderparam_t colorb; shaderparam_t blend; + shaderparam_t fog; } quake_sprite = { 0, {"spritea", 1}, @@ -88,6 +89,7 @@ static struct { {"vcolora", 0}, {"vcolorb", 0}, {"vblend", 0}, + {"fog", 0}, }; VISIBLE void @@ -110,6 +112,7 @@ R_InitSprites (void) GL_ResolveShaderParam (quake_sprite.program, &quake_sprite.colorb); GL_ResolveShaderParam (quake_sprite.program, &quake_sprite.uvab); GL_ResolveShaderParam (quake_sprite.program, &quake_sprite.blend); + GL_ResolveShaderParam (quake_sprite.program, &quake_sprite.fog); } static void @@ -311,6 +314,7 @@ void R_SpriteBegin (void) { mat4_t mat; + quat_t fog; qfglUseProgram (quake_sprite.program); qfglEnableVertexAttribArray (quake_sprite.vertexa.location); @@ -320,6 +324,10 @@ R_SpriteBegin (void) qfglDisableVertexAttribArray (quake_sprite.colorb.location); qfglDisableVertexAttribArray (quake_sprite.blend.location); + VectorCopy (Fog_GetColor (), fog); + fog[3] = Fog_GetDensity () / 64.0; + qfglUniform4fv (quake_sprite.fog.location, 1, fog); + qfglUniform1i (quake_sprite.spritea.location, 0); qfglActiveTexture (GL_TEXTURE0 + 0); qfglEnable (GL_TEXTURE_2D); diff --git a/libs/video/renderer/glsl/quakebsp.frag b/libs/video/renderer/glsl/quakebsp.frag index bfdb24fbb..d90fae044 100644 --- a/libs/video/renderer/glsl/quakebsp.frag +++ b/libs/video/renderer/glsl/quakebsp.frag @@ -1,17 +1,36 @@ uniform sampler2D colormap; uniform sampler2D texture; uniform sampler2D lightmap; +uniform vec4 fog; varying vec2 tst; varying vec2 lst; varying vec4 color; +float +sqr (float x) +{ + return x * x; +} + +vec4 +fogBlend (vec4 color) +{ + float f; + vec4 fog_color = vec4 (fog.rgb, 1.0); + + f = exp (-sqr (fog.a / gl_FragCoord.w)); + return mix (fog_color, color, f); +} + void main (void) { float pix = texture2D (texture, tst).r; float light = texture2D (lightmap, lst).r; float col; + vec4 c; - gl_FragColor = texture2D (colormap, vec2 (pix, light * 4.0)) * color; + c = texture2D (colormap, vec2 (pix, light * 4.0)) * color; + gl_FragColor = fogBlend (c); } diff --git a/libs/video/renderer/glsl/quakemdl.frag b/libs/video/renderer/glsl/quakemdl.frag index da193c843..e0e341b3b 100644 --- a/libs/video/renderer/glsl/quakemdl.frag +++ b/libs/video/renderer/glsl/quakemdl.frag @@ -3,11 +3,28 @@ uniform sampler2D skin; uniform float ambient; uniform float shadelight; uniform vec3 lightvec; +uniform vec4 fog; varying vec3 normal; varying vec2 st; varying vec4 color; +float +sqr (float x) +{ + return x * x; +} + +vec4 +fogBlend (vec4 color) +{ + float f; + vec4 fog_color = vec4 (fog.rgb, 1.0); + + f = exp (-sqr (fog.a / gl_FragCoord.w)); + return mix (fog_color, color, f); +} + void main (void) { @@ -19,5 +36,5 @@ main (void) d = min (d, 0.0); light = 255.0 - light; light += d * shadelight; - gl_FragColor = texture2D (colormap, vec2 (pix, light / 255.0)); + gl_FragColor = fogBlend (texture2D (colormap, vec2 (pix, light / 255.0))); } diff --git a/libs/video/renderer/glsl/quakepar.frag b/libs/video/renderer/glsl/quakepar.frag index 4f4e14cc0..808dea071 100644 --- a/libs/video/renderer/glsl/quakepar.frag +++ b/libs/video/renderer/glsl/quakepar.frag @@ -1,11 +1,28 @@ //precision mediump float; uniform sampler2D texture; +uniform vec4 fog; varying vec4 color; varying vec2 st; +float +sqr (float x) +{ + return x * x; +} + +vec4 +fogBlend (vec4 color) +{ + float f; + vec4 fog_color = vec4 (fog.rgb, 1.0); + + f = exp (-sqr (fog.a / gl_FragCoord.w)); + return mix (fog_color, color, f); +} + void main (void) { - gl_FragColor = texture2D (texture, st) * color; + gl_FragColor = fogBlend (texture2D (texture, st) * color); } diff --git a/libs/video/renderer/glsl/quakepnt.frag b/libs/video/renderer/glsl/quakepnt.frag index f80d74231..7b93cae74 100644 --- a/libs/video/renderer/glsl/quakepnt.frag +++ b/libs/video/renderer/glsl/quakepnt.frag @@ -1,12 +1,29 @@ //precision mediump float; uniform sampler2D palette; +uniform vec4 fog; varying float color; +float +sqr (float x) +{ + return x * x; +} + +vec4 +fogBlend (vec4 color) +{ + float f; + vec4 fog_color = vec4 (fog.rgb, 1.0); + + f = exp (-sqr (fog.a / gl_FragCoord.w)); + return mix (fog_color, color, f); +} + void main (void) { if (color == 1.0) discard; - gl_FragColor = texture2D (palette, vec2 (color, 0.0)); + gl_FragColor = fogBlend (texture2D (palette, vec2 (color, 0.0))); } diff --git a/libs/video/renderer/glsl/quakeskb.frag b/libs/video/renderer/glsl/quakeskb.frag index 10146e843..a0901e27b 100644 --- a/libs/video/renderer/glsl/quakeskb.frag +++ b/libs/video/renderer/glsl/quakeskb.frag @@ -1,7 +1,24 @@ uniform samplerCube sky; +uniform vec4 fog; varying vec3 direction; +float +sqr (float x) +{ + return x * x; +} + +vec4 +fogBlend (vec4 color) +{ + float f; + vec4 fog_color = vec4 (fog.rgb, 1.0); + + f = exp (-sqr (fog.a / gl_FragCoord.w)); + return mix (fog_color, color, f); +} + void main (void) { @@ -13,5 +30,5 @@ main (void) // quake has x right, y in, z up. gl has x right, y up, z out // The textures are loaded with GL's z (quake's y) already negated, so // all that's needed here is to swizzle y and z. - gl_FragColor = textureCube(sky, dir.xzy); + gl_FragColor = fogBlend (textureCube(sky, dir.xzy)); } diff --git a/libs/video/renderer/glsl/quakeski.frag b/libs/video/renderer/glsl/quakeski.frag index 7c83f6d75..2f82a0e68 100644 --- a/libs/video/renderer/glsl/quakeski.frag +++ b/libs/video/renderer/glsl/quakeski.frag @@ -2,11 +2,28 @@ uniform sampler2D palette; uniform sampler2D solid; uniform sampler2D trans; uniform float realtime; +uniform vec4 fog; varying vec3 direction; const float SCALE = 189.0 / 64.0; +float +sqr (float x) +{ + return x * x; +} + +vec4 +fogBlend (vec4 color) +{ + float f; + vec4 fog_color = vec4 (fog.rgb, 1.0); + + f = exp (-sqr (fog.a / gl_FragCoord.w)); + return mix (fog_color, color, f); +} + void main (void) { @@ -26,5 +43,5 @@ main (void) st = direction.xy * len + flow * realtime / 16.0; pix = texture2D (solid, st).r; } - gl_FragColor = texture2D (palette, vec2 (pix, 0.0)); + gl_FragColor = fogBlend (texture2D (palette, vec2 (pix, 0.0))); } diff --git a/libs/video/renderer/glsl/quakespr.frag b/libs/video/renderer/glsl/quakespr.frag index 0b4fa9ab7..298dbf535 100644 --- a/libs/video/renderer/glsl/quakespr.frag +++ b/libs/video/renderer/glsl/quakespr.frag @@ -1,10 +1,28 @@ uniform sampler2D spritea; uniform sampler2D spriteb; uniform sampler2D palette; +uniform vec4 fog; + varying float blend; varying vec4 colora, colorb; varying vec2 sta, stb; +float +sqr (float x) +{ + return x * x; +} + +vec4 +fogBlend (vec4 color) +{ + float f; + vec4 fog_color = vec4 (fog.rgb, 1.0); + + f = exp (-sqr (fog.a / gl_FragCoord.w)); + return mix (fog_color, color, f); +} + void main (void) { @@ -21,5 +39,5 @@ main (void) col = mix (cola, colb, blend); if (col.a == 0.0) discard; - gl_FragColor = col; + gl_FragColor = fogBlend (col); } diff --git a/libs/video/renderer/glsl/quaketrb.frag b/libs/video/renderer/glsl/quaketrb.frag index cc3f13e0a..abdc4cd8f 100644 --- a/libs/video/renderer/glsl/quaketrb.frag +++ b/libs/video/renderer/glsl/quaketrb.frag @@ -1,6 +1,7 @@ uniform sampler2D palette; uniform sampler2D texture; uniform float realtime; +uniform vec4 fog; varying vec2 tst; varying vec4 color; @@ -12,6 +13,22 @@ const float FACTOR = PI * 2.0 / CYCLE; const vec2 BIAS = vec2 (1.0, 1.0); const float SCALE = 8.0; +float +sqr (float x) +{ + return x * x; +} + +vec4 +fogBlend (vec4 color) +{ + float f; + vec4 fog_color = vec4 (fog.rgb, 1.0); + + f = exp (-sqr (fog.a / gl_FragCoord.w)); + return mix (fog_color, color, f); +} + vec2 turb_st (vec2 st, float time) { @@ -28,5 +45,5 @@ main (void) st = turb_st (tst, realtime); pix = texture2D (texture, st).r; - gl_FragColor = texture2D (palette, vec2 (pix, 0.0)) * color; + gl_FragColor = fogBlend (texture2D (palette, vec2 (pix, 0.0)) * color); }