- changed handling of DynLight in shader to serve as a global dynamic light color for all lighting modes.

This commit is contained in:
Christoph Oelckers 2014-05-11 16:49:17 +02:00
parent 53f4cd0108
commit 52056a05bd
12 changed files with 61 additions and 89 deletions

View file

@ -182,8 +182,8 @@ struct FDynLightData
bool gl_GetLight(Plane & p, ADynamicLight * light, int desaturation, bool checkside, bool forceadditive, FDynLightData &data); 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, int desaturation, bool checkside=true, bool forceadditive=true); bool gl_SetupLight(Plane & p, ADynamicLight * light, Vector & nearPt, Vector & up, Vector & right, float & scale, bool checkside=true, bool forceadditive=true);
bool gl_SetupLightTexture(); bool gl_SetupLightTexture();

View file

@ -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 // Sets up the parameters to render one dynamic light onto one plane
// //
//========================================================================== //==========================================================================
bool gl_GetLight(Plane & p, ADynamicLight * light, bool gl_GetLight(Plane & p, ADynamicLight * light, bool checkside, bool forceadditive, FDynLightData &ldata)
int desaturation, bool checkside, bool forceadditive, FDynLightData &ldata)
{ {
Vector fn, pos; Vector fn, pos;
int i = 0; int i = 0;
@ -147,14 +146,6 @@ bool gl_GetLight(Plane & p, ADynamicLight * light,
i = 1; 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)]; float *data = &ldata.arrays[i][ldata.arrays[i].Reserve(8)];
data[0] = x; data[0] = x;
data[1] = z; 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, 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; Vector fn, pos;

View file

@ -256,13 +256,15 @@ PalEntry gl_CalcLightColor(int light, PalEntry pe, int blendfactor, bool force)
} }
else 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); int mixlight = light * (255 - blendfactor);
r = (mixlight + pe.r * blendfactor) / 255; r = (mixlight + pe.r * blendfactor) / 255;
g = (mixlight + pe.g * blendfactor) / 255; g = (mixlight + pe.g * blendfactor) / 255;
b = (mixlight + pe.b * 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; 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 // 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) 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 // Check for fog boundaries. This needs a few more checks for the sectors
bool frontfog, backfog;
PalEntry fogcolor = frontsector->ColorMap->Fade; PalEntry fogcolor = frontsector->ColorMap->Fade;
if ((fogcolor.d & 0xffffff) == 0) if ((fogcolor.d & 0xffffff) == 0)
{ {
frontfog = false; return false;
} }
else if (outsidefogdensity != 0 && outsidefogcolor.a!=0xff && (fogcolor.d & 0xffffff) == (outsidefogcolor.d & 0xffffff)) else if (outsidefogdensity != 0 && outsidefogcolor.a!=0xff && (fogcolor.d & 0xffffff) == (outsidefogcolor.d & 0xffffff))
{ {
frontfog = true;
} }
else if (fogdensity!=0 || (glset.lightmode & 4)) else if (fogdensity!=0 || (glset.lightmode & 4))
{ {
// case 3: level has fog density set // case 3: level has fog density set
frontfog = true;
} }
else else
{ {
// case 4: use light level // case 4: use light level
frontfog = frontsector->lightlevel < 248; if (frontsector->lightlevel >= 248) return false;
} }
if (backsector == NULL) return frontfog;
fogcolor = backsector->ColorMap->Fade; fogcolor = backsector->ColorMap->Fade;
if ((fogcolor.d & 0xffffff) == 0) if ((fogcolor.d & 0xffffff) == 0)
{ {
backfog = false;
} }
else if (outsidefogdensity != 0 && outsidefogcolor.a!=0xff && (fogcolor.d & 0xffffff) == (outsidefogcolor.d & 0xffffff)) else if (outsidefogdensity != 0 && outsidefogcolor.a!=0xff && (fogcolor.d & 0xffffff) == (outsidefogcolor.d & 0xffffff))
{ {
backfog = true; return false;
} }
else if (fogdensity!=0 || (glset.lightmode & 4)) else if (fogdensity!=0 || (glset.lightmode & 4))
{ {
// case 3: level has fog density set // case 3: level has fog density set
backfog = true; return false;
} }
else else
{ {
// case 4: use light level // 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. // in all other cases this might create more problems than it solves.
return (frontfog && !backfog && !gl_fixedcolormap && return ((frontsector->GetTexture(sector_t::ceiling)!=skyflatnum ||
(frontsector->GetTexture(sector_t::ceiling)!=skyflatnum ||
backsector->GetTexture(sector_t::ceiling)!=skyflatnum)); backsector->GetTexture(sector_t::ceiling)!=skyflatnum));
} }

View file

@ -224,15 +224,16 @@ bool FRenderState::ApplyShader()
glUniform3iv(activeShader->lightrange_index, 1, mNumLights); glUniform3iv(activeShader->lightrange_index, 1, mNumLights);
glUniform4fv(activeShader->lights_index, mNumLights[2], mLightData); glUniform4fv(activeShader->lights_index, mNumLights[2], mLightData);
} }
if (glset.lightmode == 8)
{
glUniform3fv(activeShader->dlightcolor_index, 1, mDynLight);
}
if (mObjectColor != activeShader->currentobjectcolor) if (mObjectColor != activeShader->currentobjectcolor)
{ {
activeShader->currentobjectcolor = mObjectColor; activeShader->currentobjectcolor = mObjectColor;
glUniform4f(activeShader->objectcolor_index, mObjectColor.r / 255.f, mObjectColor.g / 255.f, mObjectColor.b / 255.f, mObjectColor.a / 255.f); 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; return true;
} }

View file

@ -95,7 +95,6 @@ class FRenderState
bool mBrightmapEnabled; bool mBrightmapEnabled;
int mSpecialEffect; int mSpecialEffect;
int mTextureMode; int mTextureMode;
float mDynLight[3];
float mLightParms[2]; float mLightParms[2];
int mNumLights[3]; int mNumLights[3];
float *mLightData; float *mLightData;
@ -113,6 +112,7 @@ class FRenderState
FStateVec4 mGlowTopPlane, mGlowBottomPlane; FStateVec4 mGlowTopPlane, mGlowBottomPlane;
PalEntry mFogColor; PalEntry mFogColor;
PalEntry mObjectColor; PalEntry mObjectColor;
PalEntry mDynColor;
float mFogDensity; float mFogDensity;
int mEffectState; int mEffectState;
@ -153,21 +153,25 @@ public:
void SetColor(float r, float g, float b, float a = 1.f, int desat = 0) void SetColor(float r, float g, float b, float a = 1.f, int desat = 0)
{ {
mColor.Set(r, g, b, a); mColor.Set(r, g, b, a);
glColor4fv(mColor.vec);
} }
void SetColor(PalEntry pe, int desat = 0) 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); 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) 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); mColor.Set(pe.r/255.f, pe.g/255.f, pe.b/255.f, alpha);
glColor4fv(mColor.vec);
} }
void ResetColor() void ResetColor()
{ {
mColor.Set(1,1,1,1); mColor.Set(1,1,1,1);
glColor4fv(mColor.vec);
} }
void SetTextureMode(int mode) void SetTextureMode(int mode)
@ -224,9 +228,12 @@ public:
void SetDynLight(float r, float g, float b) void SetDynLight(float r, float g, float b)
{ {
mDynLight[0] = r; mDynColor = PalEntry(xs_CRoundToInt(r*255), xs_CRoundToInt(g*255), xs_CRoundToInt(b*255));
mDynLight[1] = g; }
mDynLight[2] = b;
void SetDynLight(PalEntry pe)
{
mDynColor = pe;
} }
void SetFog(PalEntry c, float d) void SetFog(PalEntry c, float d)

View file

@ -143,7 +143,7 @@ void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass)
} }
p.Set(plane.plane); 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; node=node->nextLight;
continue; continue;
@ -206,7 +206,7 @@ bool GLFlat::SetupSubsectorLights(bool lightsapplied, subsector_t * sub)
} }
p.Set(plane.plane); p.Set(plane.plane);
gl_GetLight(p, light, Colormap.colormap, false, false, lightdata); gl_GetLight(p, light, false, false, lightdata);
node = node->nextLight; node = node->nextLight;
} }
} }

View file

@ -602,7 +602,7 @@ void GLSkyPortal::DrawContents()
{ {
gl_RenderState.EnableTexture(false); gl_RenderState.EnableTexture(false);
foglayer=true; 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); RenderDome(FNullTextureID(), NULL, 0, 0, false, CM_DEFAULT);
gl_RenderState.EnableTexture(true); gl_RenderState.EnableTexture(true);
foglayer=false; foglayer=false;

View file

@ -81,7 +81,7 @@ bool GLWall::PrepareLight(texcoord * tcs, ADynamicLight * light)
return false; 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; return false;
} }
@ -197,7 +197,7 @@ void GLWall::SetupLights()
} }
if (outcnt[0]!=4 && outcnt[1]!=4 && outcnt[2]!=4 && outcnt[3]!=4) 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);
} }
} }
} }

View file

@ -286,7 +286,8 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
statebright[0] = statebright[1] = true; statebright[0] = statebright[1] = true;
} }
PalEntry ThingColor = playermo->fillcolor; PalEntry ThingColor = (playermo->RenderStyle.Flags & STYLEF_ColorIsFixed) ? playermo->fillcolor : 0xffffff;
visstyle_t vis; visstyle_t vis;
vis.RenderStyle=playermo->RenderStyle; vis.RenderStyle=playermo->RenderStyle;
@ -345,6 +346,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
// now draw the different layers of the weapon // now draw the different layers of the weapon
gl_RenderState.EnableBrightmap(true); gl_RenderState.EnableBrightmap(true);
gl_RenderState.SetObjectColor(ThingColor);
if (statebright[0] || statebright[1]) if (statebright[0] || statebright[1])
{ {
// brighten the weapon to reduce the difference between // brighten the weapon to reduce the difference between
@ -365,7 +367,6 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
if (statebright[i]) if (statebright[i])
{ {
if (fakesec == viewsector || in_area != area_below) if (fakesec == viewsector || in_area != area_below)
// under water areas keep most of their color for fullbright objects
{ {
cmc.LightColor.r= cmc.LightColor.r=
cmc.LightColor.g= cmc.LightColor.g=
@ -373,7 +374,8 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
} }
else 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.g = (3*cmc.LightColor.g + 0xff)/4;
cmc.LightColor.b = (3*cmc.LightColor.b + 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); 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); gl_RenderState.EnableBrightmap(false);
glset.lightmode = oldlightmode; glset.lightmode = oldlightmode;
} }
@ -408,7 +412,7 @@ void FGLRenderer::DrawTargeterSprites()
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
gl_RenderState.AlphaFunc(GL_GEQUAL,gl_mask_sprite_threshold); gl_RenderState.AlphaFunc(GL_GEQUAL,gl_mask_sprite_threshold);
gl_RenderState.BlendEquation(GL_FUNC_ADD); gl_RenderState.BlendEquation(GL_FUNC_ADD);
glColor3f(1.0f,1.0f,1.0f); gl_RenderState.ResetColor();
gl_RenderState.SetTextureMode(TM_MODULATE); gl_RenderState.SetTextureMode(TM_MODULATE);
// The Targeter's sprites are always drawn normally. // The Targeter's sprites are always drawn normally.

View file

@ -177,6 +177,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
fogcolor_index = glGetUniformLocation(hShader, "fogcolor"); fogcolor_index = glGetUniformLocation(hShader, "fogcolor");
lights_index = glGetUniformLocation(hShader, "lights"); lights_index = glGetUniformLocation(hShader, "lights");
dlightcolor_index = glGetUniformLocation(hShader, "dlightcolor"); dlightcolor_index = glGetUniformLocation(hShader, "dlightcolor");
objectcolor_index = glGetUniformLocation(hShader, "objectcolor");
glowbottomcolor_index = glGetUniformLocation(hShader, "bottomglowcolor"); glowbottomcolor_index = glGetUniformLocation(hShader, "bottomglowcolor");
glowtopcolor_index = glGetUniformLocation(hShader, "topglowcolor"); glowtopcolor_index = glGetUniformLocation(hShader, "topglowcolor");

View file

@ -42,6 +42,7 @@ class FShader
int glowtopplane_index; int glowtopplane_index;
int objectcolor_index; int objectcolor_index;
PalEntry currentdlightcolor;
PalEntry currentobjectcolor; PalEntry currentobjectcolor;
int currentglowstate; int currentglowstate;
int currentfogenabled; int currentfogenabled;
@ -61,7 +62,7 @@ public:
currentglowstate = currentfogenabled = currenttexturemode = 0; currentglowstate = currentfogenabled = currenttexturemode = 0;
currentlightfactor = currentlightdist = 0.0f; currentlightfactor = currentlightdist = 0.0f;
currentfogdensity = -1; currentfogdensity = -1;
currentobjectcolor = currentfogcolor = 0; currentdlightcolor = currentobjectcolor = currentfogcolor = 0;
timer_index = -1; timer_index = -1;
desaturation_index = -1; desaturation_index = -1;

View file

@ -24,7 +24,7 @@ uniform vec4 lights[128];
uniform int fogenabled; uniform int fogenabled;
uniform vec4 fogcolor; uniform vec4 fogcolor;
uniform vec4 objectcolor; uniform vec4 objectcolor;
uniform vec3 dlightcolor; uniform vec4 dlightcolor;
uniform vec3 camerapos; uniform vec3 camerapos;
varying vec4 pixelpos; varying vec4 pixelpos;
varying vec4 fogparm; varying vec4 fogparm;
@ -95,7 +95,7 @@ vec4 getLightColor(float fogdist, float fogfactor)
vec4 color = gl_Color; vec4 color = gl_Color;
#ifdef SOFTLIGHT #ifdef SOFTLIGHT
float newlightlevel = 1.0 - R_DoomLightingEquation(lightlevel, gl_FragCoord.z); 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 #endif
#ifndef NO_FOG #ifndef NO_FOG
// //
@ -187,11 +187,6 @@ void main()
float fogdist = 0.0; float fogdist = 0.0;
float fogfactor = 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 #ifndef NO_FOG
// //
// calculate fog factor // calculate fog factor
@ -214,6 +209,9 @@ void main()
#ifdef DYNLIGHT #ifdef DYNLIGHT
vec4 dynlight = dlightcolor;
vec4 addlight = vec4(0.0,0.0,0.0,0.0);
for(int i=0; i<lightrange.x; i+=2) for(int i=0; i<lightrange.x; i+=2)
{ {
vec4 lightpos = lights[i]; vec4 lightpos = lights[i];
@ -238,13 +236,13 @@ void main()
lightcolor.rgb *= max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w; lightcolor.rgb *= max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w;
addlight += lightcolor; addlight += lightcolor;
} }
frag.rgb = clamp(frag.rgb + dynlight.rgb, 0.0, 1.4); frag.rgb = clamp(frag.rgb + desaturate(dynlight.rgb), 0.0, 1.4);
#endif #endif
frag = Process(frag); frag = Process(frag);
#ifdef DYNLIGHT #ifdef DYNLIGHT
frag.rgb += addlight.rgb; frag.rgb += desaturate(addlight.rgb);
#endif #endif
#ifndef NO_FOG #ifndef NO_FOG