Skip to content

Commit

Permalink
Model Renderer: Added fog to the model shaders
Browse files Browse the repository at this point in the history
The fog start/end depths and the near/far clipping planes are passed
to the model shaders, which are expected to use "include/fog.glsl"
in their fragment shader.

The fog GL parameters were slightly refactored by moving them into
a single struct.
  • Loading branch information
skyjake committed Nov 5, 2015
1 parent a4975a3 commit 482f3aa
Show file tree
Hide file tree
Showing 12 changed files with 145 additions and 55 deletions.
2 changes: 2 additions & 0 deletions doomsday/apps/client/include/gl/gl_main.h
Expand Up @@ -131,6 +131,8 @@ void GL_Restore2DState(int step, viewport_t const *port, viewdata_t const *viewD

void GL_ProjectionMatrix();

de::Rangef GL_DepthClipRange();

/**
* Returns the projection matrix that is used for rendering the current frame's
* 3D portions.
Expand Down
16 changes: 12 additions & 4 deletions doomsday/apps/client/include/render/rend_main.h
Expand Up @@ -44,12 +44,12 @@ class LightGrid;
}

// Multiplicative blending for dynamic lights?
#define IS_MUL (dynlightBlend != 1 && !usingFog)
#define IS_MUL (dynlightBlend != 1 && !fogParams.usingFog)

#define MTEX_DETAILS_ENABLED (r_detail && useMultiTexDetails && \
defs.details.size() > 0)
#define IS_MTEX_DETAILS (MTEX_DETAILS_ENABLED && numTexUnits > 1)
#define IS_MTEX_LIGHTS (!IS_MTEX_DETAILS && !usingFog && useMultiTexLights \
#define IS_MTEX_LIGHTS (!IS_MTEX_DETAILS && !fogParams.usingFog && useMultiTexLights \
&& numTexUnits > 1 && envModAdd)

#define GLOW_HEIGHT_MAX (1024.f) /// Absolute maximum
Expand All @@ -61,10 +61,18 @@ class LightGrid;
DENG_EXTERN_C de::Vector3d vOrigin; // Y/Z swizzled for drawing
DENG_EXTERN_C float vang, vpitch, yfov;
DENG_EXTERN_C float viewsidex, viewsidey;
DENG_EXTERN_C float fogColor[4];

struct FogParams
{
bool usingFog;
float fogColor[4];
float fogStart;
float fogEnd;
};

extern FogParams fogParams;

DENG_EXTERN_C byte smoothTexAnim, devMobjVLights;
DENG_EXTERN_C dd_bool usingFog;

DENG_EXTERN_C int renderTextures; /// @c 0= no textures, @c 1= normal mode, @c 2= lighting debug
DENG_EXTERN_C int renderWireframe;
Expand Down
@@ -0,0 +1,40 @@
/*
* The Doomsday Engine Project
* Common OpenGL Shaders: Fog (fragment shader)
*
* Copyright (c) 2015 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* @par License
* LGPL: http://www.gnu.org/licenses/lgpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3 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 Lesser
* General Public License for more details. You should have received a copy of
* the GNU Lesser General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
*/

uniform highp vec4 uFogRange; // startDepth, fogDepth, nearclip, farclip
uniform highp vec4 uFogColor; // set alpha to zero to disable fog

void applyFog()
{
if(uFogColor.a > 0.0)
{
highp float near = uFogRange.z;
highp float far = uFogRange.w;

// First convert the fragment Z back to view space.
highp float zNorm = gl_FragCoord.z * 2.0 - 1.0;
highp float zEye = -2.0 * far * near / (zNorm * (far - near) - (far + near));

highp float fogAmount = clamp((zEye - uFogRange.x) / uFogRange.y, 0.0, 1.0);
gl_FragColor.rgb = mix(gl_FragColor.rgb, uFogColor.rgb, fogAmount);

// gl_FragColor.rgb = vec3(zEye, 0.0, normZ);
}
}
Expand Up @@ -46,7 +46,8 @@ model.skeletal {
}"

include.fragment <include/texture.glsl,
include/lighting.glsl>
include/lighting.glsl,
include/fog.glsl>
fragment = "
uniform highp float uAlpha;
uniform highp float uAlphaLimit; // alpha test to discard fragments
Expand Down Expand Up @@ -79,6 +80,8 @@ model.skeletal {
gl_FragColor.a = min(1.0, diffuse.a + specular.a);

if(gl_FragColor.a < uAlphaLimit) discard;

applyFog();
}"
}

Expand Down Expand Up @@ -126,7 +129,8 @@ model.skeletal {
}"

include.fragment <include/texture.glsl,
include/lighting.glsl>
include/lighting.glsl,
include/fog.glsl>
fragment = "
uniform highp float uAlphaLimit;

Expand All @@ -152,6 +156,8 @@ model.skeletal {

// All accepted fragments are opaque.
gl_FragColor.a = 1.0;

applyFog();
}"
}
}
2 changes: 1 addition & 1 deletion doomsday/apps/client/src/dd_main.cpp
Expand Up @@ -2247,7 +2247,7 @@ void DD_UpdateEngineState()
}

#ifdef __CLIENT__
dd_bool hadFog = usingFog;
dd_bool hadFog = fogParams.usingFog;

GL_TotalReset();
GL_TotalRestore(); // Bring GL back online.
Expand Down
32 changes: 20 additions & 12 deletions doomsday/apps/client/src/gl/gl_main.cpp
Expand Up @@ -379,18 +379,18 @@ void GL_Init2DState()
glOrtho(0, 320, 200, 0, -1, 1);

// Default state for the white fog is off.
usingFog = false;
fogParams.usingFog = false;
glDisable(GL_FOG);
glFogi(GL_FOG_MODE, (fogModeDefault == 0 ? GL_LINEAR :
fogModeDefault == 1 ? GL_EXP : GL_EXP2));
glFogf(GL_FOG_START, DEFAULT_FOG_START);
glFogf(GL_FOG_END, DEFAULT_FOG_END);
glFogf(GL_FOG_DENSITY, DEFAULT_FOG_DENSITY);
fogColor[0] = DEFAULT_FOG_COLOR_RED;
fogColor[1] = DEFAULT_FOG_COLOR_GREEN;
fogColor[2] = DEFAULT_FOG_COLOR_BLUE;
fogColor[3] = 1;
glFogfv(GL_FOG_COLOR, fogColor);
fogParams.fogColor[0] = DEFAULT_FOG_COLOR_RED;
fogParams.fogColor[1] = DEFAULT_FOG_COLOR_GREEN;
fogParams.fogColor[2] = DEFAULT_FOG_COLOR_BLUE;
fogParams.fogColor[3] = 1;
glFogfv(GL_FOG_COLOR, fogParams.fogColor);
}

void GL_SwitchTo3DState(dd_bool push_state, viewport_t const *port, viewdata_t const *viewData)
Expand Down Expand Up @@ -499,6 +499,11 @@ void GL_Restore2DState(dint step, viewport_t const *port, viewdata_t const *view
}
}

Rangef GL_DepthClipRange()
{
return Rangef(glNearClip, glFarClip);
}

Matrix4f GL_GetProjectionMatrix()
{
dfloat const fov = Rend_FieldOfView();
Expand Down Expand Up @@ -553,7 +558,7 @@ void GL_SetupFogFromMapInfo(Record const *mapInfo)
#undef GL_UseFog
DENG_EXTERN_C void GL_UseFog(dint yes)
{
usingFog = yes;
fogParams.usingFog = yes;
}

void GL_SelectTexUnits(dint count)
Expand Down Expand Up @@ -1547,23 +1552,26 @@ D_CMD(Fog)
{
for(dint i = 0; i < 3; ++i)
{
fogColor[i] = strtol(argv[2 + i], nullptr, 0) / 255.0f;
fogParams.fogColor[i] = strtol(argv[2 + i], nullptr, 0) / 255.0f;
}
fogColor[3] = 1;
fogParams.fogColor[3] = 1;

glFogfv(GL_FOG_COLOR, fogColor);
glFogfv(GL_FOG_COLOR, fogParams.fogColor);
LOG_GL_VERBOSE("Fog color set");
return true;
}
if(!stricmp(argv[1], "start") && argc == 3)
{
glFogf(GL_FOG_START, (GLfloat) strtod(argv[2], nullptr));
fogParams.fogStart = (GLfloat) strtod(argv[2], nullptr);

glFogf(GL_FOG_START, fogParams.fogStart);
LOG_GL_VERBOSE("Fog start distance set");
return true;
}
if(!stricmp(argv[1], "end") && argc == 3)
{
glFogf(GL_FOG_END, (GLfloat) strtod(argv[2], nullptr));
fogParams.fogEnd = (GLfloat) strtod(argv[2], nullptr);
glFogf(GL_FOG_END, fogParams.fogEnd);
LOG_GL_VERBOSE("Fog end distance set");
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion doomsday/apps/client/src/render/api_render.cpp
Expand Up @@ -198,7 +198,7 @@ DENG_EXTERN_C void R_SetupFog(dfloat start, dfloat end, dfloat density, dfloat *
DENG_EXTERN_C void R_SetupFogDefaults()
{
// Go with the defaults.
Con_Execute(CMDS_DDAY,"fog off", true, false);
Con_Execute(CMDS_DDAY, "fog off", true, false);
}

DENG_DECLARE_API(Rend) =
Expand Down
29 changes: 28 additions & 1 deletion doomsday/apps/client/src/render/modelrenderer.cpp
Expand Up @@ -130,6 +130,8 @@ DENG2_PIMPL(ModelRenderer)
GLUniform uAmbientLight { "uAmbientLight", GLUniform::Vec4 };
GLUniform uLightDirs { "uLightDirs", GLUniform::Vec3Array, MAX_LIGHTS };
GLUniform uLightIntensities { "uLightIntensities", GLUniform::Vec4Array, MAX_LIGHTS };
GLUniform uFogRange { "uFogRange", GLUniform::Vec4 };
GLUniform uFogColor { "uFogColor", GLUniform::Vec4 };

Matrix4f inverseLocal;
int lightCount = 0;
Expand Down Expand Up @@ -229,7 +231,9 @@ DENG2_PIMPL(ModelRenderer)
<< uEyePos
<< uAmbientLight
<< uLightDirs
<< uLightIntensities;
<< uLightIntensities
<< uFogRange
<< uFogColor;

programs[name] = prog.get();
return prog.release();
Expand Down Expand Up @@ -614,9 +618,32 @@ DENG2_PIMPL(ModelRenderer)
lightCount++;
}

void setupFog()
{
if(fogParams.usingFog)
{
uFogColor = Vector4f(fogParams.fogColor[0],
fogParams.fogColor[1],
fogParams.fogColor[2],
1.f);

Rangef const depthPlanes = GL_DepthClipRange();
float const fogDepth = fogParams.fogEnd - fogParams.fogStart;
uFogRange = Vector4f(fogParams.fogStart,
fogDepth,
depthPlanes.start,
depthPlanes.end);
}
else
{
uFogColor = Vector4f();
}
}

template <typename Params> // generic to accommodate psprites and vispsprites
void draw(Params const &p)
{
setupFog();
uTex = static_cast<AtlasTexture const *>(p.model->textures->atlas());

p.model->draw(&p.animator->appearance(), p.animator);
Expand Down
4 changes: 2 additions & 2 deletions doomsday/apps/client/src/render/r_main.cpp
Expand Up @@ -173,7 +173,7 @@ void Rend_Draw2DPlayerSprites()
if(ddpl.flags & DDPF_CAMERA ) return;
if(ddpl.flags & DDPF_CHASECAM) return;

if(usingFog)
if(fogParams.usingFog)
{
glEnable(GL_FOG);
}
Expand Down Expand Up @@ -201,7 +201,7 @@ void Rend_Draw2DPlayerSprites()
}
}

if(usingFog)
if(fogParams.usingFog)
{
glDisable(GL_FOG);
}
Expand Down

0 comments on commit 482f3aa

Please sign in to comment.