From 52056a05bda71b47740ebc5567fe367df8d2f5fc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 11 May 2014 16:49:17 +0200 Subject: [PATCH] - changed handling of DynLight in shader to serve as a global dynamic light color for all lighting modes. --- src/gl/dynlights/gl_dynlight.h | 4 +- src/gl/dynlights/gl_dynlight1.cpp | 13 +----- src/gl/renderer/gl_lightdata.cpp | 67 ++++++++---------------------- src/gl/renderer/gl_renderstate.cpp | 9 ++-- src/gl/renderer/gl_renderstate.h | 15 +++++-- src/gl/scene/gl_flats.cpp | 4 +- src/gl/scene/gl_skydome.cpp | 2 +- src/gl/scene/gl_walls_draw.cpp | 4 +- src/gl/scene/gl_weapon.cpp | 12 ++++-- src/gl/shaders/gl_shader.cpp | 1 + src/gl/shaders/gl_shader.h | 3 +- wadsrc/static/shaders/glsl/main.fp | 16 ++++--- 12 files changed, 61 insertions(+), 89 deletions(-) diff --git a/src/gl/dynlights/gl_dynlight.h b/src/gl/dynlights/gl_dynlight.h index ca3b2ec90..dbf89324b 100644 --- a/src/gl/dynlights/gl_dynlight.h +++ b/src/gl/dynlights/gl_dynlight.h @@ -182,8 +182,8 @@ struct FDynLightData -bool gl_GetLight(Plane & p, ADynamicLight * light, int desaturation, bool checkside, bool forceadditive, FDynLightData &data); -bool gl_SetupLight(Plane & p, ADynamicLight * light, Vector & nearPt, Vector & up, Vector & right, float & scale, int desaturation, bool checkside=true, bool forceadditive=true); +bool gl_GetLight(Plane & p, ADynamicLight * light, bool checkside, bool forceadditive, FDynLightData &data); +bool gl_SetupLight(Plane & p, ADynamicLight * light, Vector & nearPt, Vector & up, Vector & right, float & scale, bool checkside=true, bool forceadditive=true); bool gl_SetupLightTexture(); diff --git a/src/gl/dynlights/gl_dynlight1.cpp b/src/gl/dynlights/gl_dynlight1.cpp index 57da56b40..90d65559c 100644 --- a/src/gl/dynlights/gl_dynlight1.cpp +++ b/src/gl/dynlights/gl_dynlight1.cpp @@ -100,8 +100,7 @@ CUSTOM_CVAR (Bool, gl_lights_additive, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG // Sets up the parameters to render one dynamic light onto one plane // //========================================================================== -bool gl_GetLight(Plane & p, ADynamicLight * light, - int desaturation, bool checkside, bool forceadditive, FDynLightData &ldata) +bool gl_GetLight(Plane & p, ADynamicLight * light, bool checkside, bool forceadditive, FDynLightData &ldata) { Vector fn, pos; int i = 0; @@ -147,14 +146,6 @@ bool gl_GetLight(Plane & p, ADynamicLight * light, i = 1; } - if (desaturation>0) - { - float gray=(r*77 + g*143 + b*37)/257; - - r= (r*(32-desaturation)+ gray*desaturation)/32; - g= (g*(32-desaturation)+ gray*desaturation)/32; - b= (b*(32-desaturation)+ gray*desaturation)/32; - } float *data = &ldata.arrays[i][ldata.arrays[i].Reserve(8)]; data[0] = x; data[1] = z; @@ -176,7 +167,7 @@ bool gl_GetLight(Plane & p, ADynamicLight * light, // //========================================================================== bool gl_SetupLight(Plane & p, ADynamicLight * light, Vector & nearPt, Vector & up, Vector & right, - float & scale, int desaturation, bool checkside, bool forceadditive) + float & scale, bool checkside, bool forceadditive) { Vector fn, pos; diff --git a/src/gl/renderer/gl_lightdata.cpp b/src/gl/renderer/gl_lightdata.cpp index 0660f04c2..1ceb609c8 100644 --- a/src/gl/renderer/gl_lightdata.cpp +++ b/src/gl/renderer/gl_lightdata.cpp @@ -256,13 +256,15 @@ PalEntry gl_CalcLightColor(int light, PalEntry pe, int blendfactor, bool force) } else { + // This is what Legacy does with colored light in 3D volumes. No, it doesn't really make sense... + // It also doesn't translate well to software style lighting. int mixlight = light * (255 - blendfactor); r = (mixlight + pe.r * blendfactor) / 255; g = (mixlight + pe.g * blendfactor) / 255; b = (mixlight + pe.b * blendfactor) / 255; } - return PalEntry(BYTE(r), BYTE(g), BYTE(b)); + return PalEntry(255, BYTE(r), BYTE(g), BYTE(b)); } //========================================================================== @@ -373,7 +375,7 @@ void gl_SetColor(int light, int rellight, const FColormap * cm, float alpha, Pal // //========================================================================== -float gl_GetFogDensity(int lightlevel, PalEntry fogcolor) +static float gl_GetFogDensity(int lightlevel, PalEntry fogcolor) { float density; @@ -417,98 +419,65 @@ float gl_GetFogDensity(int lightlevel, PalEntry fogcolor) } -//========================================================================== -// -// Check fog by current lighting info -// -//========================================================================== - -bool gl_CheckFog(FColormap *cm, int lightlevel) -{ - // Check for fog boundaries. This needs a few more checks for the sectors - bool frontfog; - - PalEntry fogcolor = cm->FadeColor; - - if ((fogcolor.d & 0xffffff) == 0) - { - frontfog = false; - } - else if (outsidefogdensity != 0 && outsidefogcolor.a!=0xff && (fogcolor.d & 0xffffff) == (outsidefogcolor.d & 0xffffff)) - { - frontfog = true; - } - else if (fogdensity!=0 || (glset.lightmode & 4)) - { - // case 3: level has fog density set - frontfog = true; - } - else - { - // case 4: use light level - frontfog = lightlevel < 248; - } - return frontfog; -} - //========================================================================== // // Check if the current linedef is a candidate for a fog boundary // +// Requirements for a fog boundary: +// - front sector has no fog +// - back sector has fog +// - at least one of both does not have a sky ceiling. +// //========================================================================== bool gl_CheckFog(sector_t *frontsector, sector_t *backsector) { + if (gl_fixedcolormap) return false; + if (frontsector == backsector) return false; // there can't be a boundary if both sides are in the same sector. + // Check for fog boundaries. This needs a few more checks for the sectors - bool frontfog, backfog; PalEntry fogcolor = frontsector->ColorMap->Fade; if ((fogcolor.d & 0xffffff) == 0) { - frontfog = false; + return false; } else if (outsidefogdensity != 0 && outsidefogcolor.a!=0xff && (fogcolor.d & 0xffffff) == (outsidefogcolor.d & 0xffffff)) { - frontfog = true; } else if (fogdensity!=0 || (glset.lightmode & 4)) { // case 3: level has fog density set - frontfog = true; } else { // case 4: use light level - frontfog = frontsector->lightlevel < 248; + if (frontsector->lightlevel >= 248) return false; } - if (backsector == NULL) return frontfog; - fogcolor = backsector->ColorMap->Fade; if ((fogcolor.d & 0xffffff) == 0) { - backfog = false; } else if (outsidefogdensity != 0 && outsidefogcolor.a!=0xff && (fogcolor.d & 0xffffff) == (outsidefogcolor.d & 0xffffff)) { - backfog = true; + return false; } else if (fogdensity!=0 || (glset.lightmode & 4)) { // case 3: level has fog density set - backfog = true; + return false; } else { // case 4: use light level - backfog = backsector->lightlevel < 248; + if (backsector->lightlevel < 248) return false; } // in all other cases this might create more problems than it solves. - return (frontfog && !backfog && !gl_fixedcolormap && - (frontsector->GetTexture(sector_t::ceiling)!=skyflatnum || + return ((frontsector->GetTexture(sector_t::ceiling)!=skyflatnum || backsector->GetTexture(sector_t::ceiling)!=skyflatnum)); } diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 84f270e06..96b782771 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -224,15 +224,16 @@ bool FRenderState::ApplyShader() glUniform3iv(activeShader->lightrange_index, 1, mNumLights); glUniform4fv(activeShader->lights_index, mNumLights[2], mLightData); } - if (glset.lightmode == 8) - { - glUniform3fv(activeShader->dlightcolor_index, 1, mDynLight); - } if (mObjectColor != activeShader->currentobjectcolor) { activeShader->currentobjectcolor = mObjectColor; glUniform4f(activeShader->objectcolor_index, mObjectColor.r / 255.f, mObjectColor.g / 255.f, mObjectColor.b / 255.f, mObjectColor.a / 255.f); } + if (mDynColor != activeShader->currentdlightcolor) + { + activeShader->currentobjectcolor = mObjectColor; + glUniform4f(activeShader->dlightcolor_index, mDynColor.r / 255.f, mDynColor.g / 255.f, mDynColor.b / 255.f, 0); + } return true; } diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 35f5795a2..2c2c43605 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -95,7 +95,6 @@ class FRenderState bool mBrightmapEnabled; int mSpecialEffect; int mTextureMode; - float mDynLight[3]; float mLightParms[2]; int mNumLights[3]; float *mLightData; @@ -113,6 +112,7 @@ class FRenderState FStateVec4 mGlowTopPlane, mGlowBottomPlane; PalEntry mFogColor; PalEntry mObjectColor; + PalEntry mDynColor; float mFogDensity; int mEffectState; @@ -153,21 +153,25 @@ public: void SetColor(float r, float g, float b, float a = 1.f, int desat = 0) { mColor.Set(r, g, b, a); + glColor4fv(mColor.vec); } void SetColor(PalEntry pe, int desat = 0) { mColor.Set(pe.r/255.f, pe.g/255.f, pe.b/255.f, pe.a/255.f); + glColor4fv(mColor.vec); } void SetColorAlpha(PalEntry pe, float alpha = 1.f, int desat = 0) { mColor.Set(pe.r/255.f, pe.g/255.f, pe.b/255.f, alpha); + glColor4fv(mColor.vec); } void ResetColor() { mColor.Set(1,1,1,1); + glColor4fv(mColor.vec); } void SetTextureMode(int mode) @@ -224,9 +228,12 @@ public: void SetDynLight(float r, float g, float b) { - mDynLight[0] = r; - mDynLight[1] = g; - mDynLight[2] = b; + mDynColor = PalEntry(xs_CRoundToInt(r*255), xs_CRoundToInt(g*255), xs_CRoundToInt(b*255)); + } + + void SetDynLight(PalEntry pe) + { + mDynColor = pe; } void SetFog(PalEntry c, float d) diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index f24db1fdd..4a4c0d715 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -143,7 +143,7 @@ void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass) } p.Set(plane.plane); - if (!gl_SetupLight(p, light, nearPt, up, right, scale, Colormap.colormap, false, foggy)) + if (!gl_SetupLight(p, light, nearPt, up, right, scale, false, foggy)) { node=node->nextLight; continue; @@ -206,7 +206,7 @@ bool GLFlat::SetupSubsectorLights(bool lightsapplied, subsector_t * sub) } p.Set(plane.plane); - gl_GetLight(p, light, Colormap.colormap, false, false, lightdata); + gl_GetLight(p, light, false, false, lightdata); node = node->nextLight; } } diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index dee3ea4e3..7dbf5e573 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -602,7 +602,7 @@ void GLSkyPortal::DrawContents() { gl_RenderState.EnableTexture(false); foglayer=true; - glColor4f(FadeColor.r/255.0f,FadeColor.g/255.0f,FadeColor.b/255.0f,skyfog/255.0f); + gl_RenderState.SetColorAlpha(FadeColor, skyfog / 255.0f); RenderDome(FNullTextureID(), NULL, 0, 0, false, CM_DEFAULT); gl_RenderState.EnableTexture(true); foglayer=false; diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 7f7538dc4..b4af1e28d 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -81,7 +81,7 @@ bool GLWall::PrepareLight(texcoord * tcs, ADynamicLight * light) return false; } - if (!gl_SetupLight(p, light, nearPt, up, right, scale, Colormap.colormap, true, !!(flags&GLWF_FOGGY))) + if (!gl_SetupLight(p, light, nearPt, up, right, scale, true, !!(flags&GLWF_FOGGY))) { return false; } @@ -197,7 +197,7 @@ void GLWall::SetupLights() } if (outcnt[0]!=4 && outcnt[1]!=4 && outcnt[2]!=4 && outcnt[3]!=4) { - gl_GetLight(p, node->lightsource, Colormap.colormap, true, false, lightdata); + gl_GetLight(p, node->lightsource, true, false, lightdata); } } } diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index fe3aee0ff..c9f8434c4 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -286,7 +286,8 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) statebright[0] = statebright[1] = true; } - PalEntry ThingColor = playermo->fillcolor; + PalEntry ThingColor = (playermo->RenderStyle.Flags & STYLEF_ColorIsFixed) ? playermo->fillcolor : 0xffffff; + visstyle_t vis; vis.RenderStyle=playermo->RenderStyle; @@ -345,6 +346,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) // now draw the different layers of the weapon gl_RenderState.EnableBrightmap(true); + gl_RenderState.SetObjectColor(ThingColor); if (statebright[0] || statebright[1]) { // brighten the weapon to reduce the difference between @@ -365,7 +367,6 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) if (statebright[i]) { if (fakesec == viewsector || in_area != area_below) - // under water areas keep most of their color for fullbright objects { cmc.LightColor.r= cmc.LightColor.g= @@ -373,7 +374,8 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) } else { - cmc.LightColor.r = (3*cmc.LightColor.r + 0xff)/4; + // under water areas keep most of their color for fullbright objects + cmc.LightColor.r = (3 * cmc.LightColor.r + 0xff) / 4; cmc.LightColor.g = (3*cmc.LightColor.g + 0xff)/4; cmc.LightColor.b = (3*cmc.LightColor.b + 0xff)/4; } @@ -384,6 +386,8 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) DrawPSprite (player,psp,psp->sx+ofsx, psp->sy+ofsy, cm.colormap, hudModelStep, OverrideShader); } } + gl_RenderState.SetObjectColor(0xffffffff); + gl_RenderState.SetDynLight(0, 0, 0); gl_RenderState.EnableBrightmap(false); glset.lightmode = oldlightmode; } @@ -408,7 +412,7 @@ void FGLRenderer::DrawTargeterSprites() gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_RenderState.AlphaFunc(GL_GEQUAL,gl_mask_sprite_threshold); gl_RenderState.BlendEquation(GL_FUNC_ADD); - glColor3f(1.0f,1.0f,1.0f); + gl_RenderState.ResetColor(); gl_RenderState.SetTextureMode(TM_MODULATE); // The Targeter's sprites are always drawn normally. diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 2065768fa..8f993b857 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -177,6 +177,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * fogcolor_index = glGetUniformLocation(hShader, "fogcolor"); lights_index = glGetUniformLocation(hShader, "lights"); dlightcolor_index = glGetUniformLocation(hShader, "dlightcolor"); + objectcolor_index = glGetUniformLocation(hShader, "objectcolor"); glowbottomcolor_index = glGetUniformLocation(hShader, "bottomglowcolor"); glowtopcolor_index = glGetUniformLocation(hShader, "topglowcolor"); diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index 4b0c37e1e..62c87c1f9 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -42,6 +42,7 @@ class FShader int glowtopplane_index; int objectcolor_index; + PalEntry currentdlightcolor; PalEntry currentobjectcolor; int currentglowstate; int currentfogenabled; @@ -61,7 +62,7 @@ public: currentglowstate = currentfogenabled = currenttexturemode = 0; currentlightfactor = currentlightdist = 0.0f; currentfogdensity = -1; - currentobjectcolor = currentfogcolor = 0; + currentdlightcolor = currentobjectcolor = currentfogcolor = 0; timer_index = -1; desaturation_index = -1; diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index a99ffa330..8587b5ac3 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -24,7 +24,7 @@ uniform vec4 lights[128]; uniform int fogenabled; uniform vec4 fogcolor; uniform vec4 objectcolor; -uniform vec3 dlightcolor; +uniform vec4 dlightcolor; uniform vec3 camerapos; varying vec4 pixelpos; varying vec4 fogparm; @@ -95,7 +95,7 @@ vec4 getLightColor(float fogdist, float fogfactor) vec4 color = gl_Color; #ifdef SOFTLIGHT float newlightlevel = 1.0 - R_DoomLightingEquation(lightlevel, gl_FragCoord.z); - color.rgb *= clamp(vec3(newlightlevel) + dlightcolor, 0.0, 1.0); + color.rgb *= clamp(vec3(newlightlevel), 0.0, 1.0); #endif #ifndef NO_FOG // @@ -187,11 +187,6 @@ void main() float fogdist = 0.0; float fogfactor = 0.0; - #ifdef DYNLIGHT - vec4 dynlight = vec4(0.0,0.0,0.0,0.0); - vec4 addlight = vec4(0.0,0.0,0.0,0.0); - #endif - #ifndef NO_FOG // // calculate fog factor @@ -214,6 +209,9 @@ void main() #ifdef DYNLIGHT + vec4 dynlight = dlightcolor; + vec4 addlight = vec4(0.0,0.0,0.0,0.0); + for(int i=0; i