- disabled forced additive dynamic lights when shader light is on.

The shader can easily handle proper light and fog simultaneously and 
  it looks much better like this,

git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@542 b0f79afe-0144-0410-b225-9a4edf0717df
This commit is contained in:
Christoph Oelckers 2009-10-11 21:00:50 +00:00
parent 8268f773b1
commit 39e57a292a
5 changed files with 86 additions and 67 deletions

View file

@ -52,6 +52,7 @@ enum Drawpasses
GLPASS_DECALS, // Draws a decal
GLPASS_DECALS_NOFOG,// Draws a decal without setting the fog (used for passes that need a fog layer)
GLPASS_TRANSLUCENT, // Draws translucent objects
GLPASS_ALL // Everything at once, using shaders for dynamic lights
};
//==========================================================================

View file

@ -163,52 +163,49 @@ extern FDynLightData lightdata;
bool GLFlat::SetupSubsectorLights(bool lightsapplied, subsector_t * sub)
{
if (gl_dynlight_shader && GLRenderer->mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT)
Plane p;
lightdata.Clear();
for(int i=0;i<2;i++)
{
Plane p;
lightdata.Clear();
for(int i=0;i<2;i++)
FLightNode * node = sub->lighthead[i];
while (node)
{
FLightNode * node = sub->lighthead[i];
while (node)
ADynamicLight * light = node->lightsource;
if (light->flags2&MF2_DORMANT)
{
ADynamicLight * light = node->lightsource;
if (light->flags2&MF2_DORMANT)
{
node=node->nextLight;
continue;
}
iter_dlightf++;
// we must do the side check here because gl_SetupLight needs the correct plane orientation
// which we don't have for Legacy-style 3D-floors
fixed_t planeh = plane.plane.ZatPoint(light->x, light->y);
if (gl_lights_checkside && ((planeh<light->z && ceiling) || (planeh>light->z && !ceiling)))
{
node=node->nextLight;
continue;
}
p.Set(plane.plane);
gl_GetLight(p, light, Colormap.colormap, false, foggy, lightdata);
node = node->nextLight;
node=node->nextLight;
continue;
}
}
iter_dlightf++;
int numlights[3];
// we must do the side check here because gl_SetupLight needs the correct plane orientation
// which we don't have for Legacy-style 3D-floors
fixed_t planeh = plane.plane.ZatPoint(light->x, light->y);
if (gl_lights_checkside && ((planeh<light->z && ceiling) || (planeh>light->z && !ceiling)))
{
node=node->nextLight;
continue;
}
lightdata.Combine(numlights, gl.MaxLights());
if (numlights[2] > 0)
{
draw_dlightf+=numlights[2]/2;
gl_RenderState.EnableLight(true);
gl_RenderState.SetLights(numlights, &lightdata.arrays[0][0]);
gl_RenderState.Apply();
return true;
p.Set(plane.plane);
gl_GetLight(p, light, Colormap.colormap, false, false, lightdata);
node = node->nextLight;
}
}
int numlights[3];
lightdata.Combine(numlights, gl.MaxLights());
if (numlights[2] > 0)
{
draw_dlightf+=numlights[2]/2;
gl_RenderState.EnableLight(true);
gl_RenderState.SetLights(numlights, &lightdata.arrays[0][0]);
gl_RenderState.Apply();
return true;
}
if (lightsapplied)
{
gl_RenderState.EnableLight(false);
@ -254,7 +251,7 @@ void GLFlat::DrawSubsectors(int pass, bool istrans)
if (sub)
{
// This represents a single subsector
if (pass == GLPASS_PLAIN) lightsapplied = SetupSubsectorLights(lightsapplied, sub);
if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, sub);
DrawSubsector(sub);
}
else
@ -269,7 +266,7 @@ void GLFlat::DrawSubsectors(int pass, bool istrans)
// This is just a quick hack to make translucent 3D floors and portals work.
if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans)
{
if (pass == GLPASS_PLAIN) lightsapplied = SetupSubsectorLights(lightsapplied, sub);
if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, sub);
gl.DrawArrays(GL_TRIANGLE_FAN, index, sub->numlines);
flatvertices += sub->numlines;
flatprimitives++;
@ -286,7 +283,7 @@ void GLFlat::DrawSubsectors(int pass, bool istrans)
subsector_t * sub = sector->subsectors[i];
if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans)
{
if (pass == GLPASS_PLAIN) lightsapplied = SetupSubsectorLights(lightsapplied, sub);
if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, sub);
DrawSubsector(sub);
}
}
@ -301,7 +298,7 @@ void GLFlat::DrawSubsectors(int pass, bool istrans)
while (node)
{
if (pass == GLPASS_PLAIN) lightsapplied = SetupSubsectorLights(lightsapplied, node->sub);
if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, node->sub);
DrawSubsector(node->sub);
node = node->next;
}
@ -338,11 +335,10 @@ void GLFlat::Draw(int pass)
break;
case GLPASS_PLAIN: // Single-pass rendering
case GLPASS_ALL:
case GLPASS_BASE_MASKED:
gl_SetColor(lightlevel, rel, &Colormap,1.0f);
if (!foggy || pass == GLPASS_PLAIN)
gl_SetFog(lightlevel, rel, &Colormap, false);
if (!foggy || pass != GLPASS_BASE_MASKED) gl_SetFog(lightlevel, rel, &Colormap, false);
// fall through
case GLPASS_TEXTURE:
gltexture->Bind(Colormap.colormap);

View file

@ -344,15 +344,30 @@ void FGLRenderer::RenderScene(int recursion)
gl.Disable(GL_POLYGON_OFFSET_FILL); // just in case
int pass;
if (mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights && gl_dynlight_shader)
{
pass = GLPASS_ALL;
}
else if (gl_texture)
{
pass = GLPASS_PLAIN;
}
else
{
pass = GLPASS_BASE;
}
gl_RenderState.EnableTexture(gl_texture);
gl_RenderState.EnableBrightmap(true);
gl_drawinfo->drawlists[GLDL_PLAIN].Sort();
gl_drawinfo->drawlists[GLDL_PLAIN].Draw(gl_texture? GLPASS_PLAIN : GLPASS_BASE);
gl_drawinfo->drawlists[GLDL_PLAIN].Draw(pass);
gl_RenderState.EnableBrightmap(false);
gl_drawinfo->drawlists[GLDL_FOG].Sort();
gl_drawinfo->drawlists[GLDL_FOG].Draw(gl_texture? GLPASS_PLAIN : GLPASS_BASE);
gl_drawinfo->drawlists[GLDL_FOG].Draw(pass);
gl_drawinfo->drawlists[GLDL_LIGHTFOG].Sort();
gl_drawinfo->drawlists[GLDL_LIGHTFOG].Draw(gl_texture? GLPASS_PLAIN : GLPASS_BASE);
gl_drawinfo->drawlists[GLDL_LIGHTFOG].Draw(pass);
gl.Enable(GL_ALPHA_TEST);
@ -363,18 +378,19 @@ void FGLRenderer::RenderScene(int recursion)
gl_RenderState.EnableTexture(true);
gl_RenderState.SetTextureMode(TM_MASK);
}
if (pass == GLPASS_BASE) pass = GLPASS_BASE_MASKED;
gl.AlphaFunc(GL_GEQUAL,gl_mask_threshold);
gl_RenderState.EnableBrightmap(true);
gl_drawinfo->drawlists[GLDL_MASKED].Sort();
gl_drawinfo->drawlists[GLDL_MASKED].Draw(gl_texture? GLPASS_PLAIN : GLPASS_BASE_MASKED);
gl_drawinfo->drawlists[GLDL_MASKED].Draw(pass);
gl_RenderState.EnableBrightmap(false);
gl_drawinfo->drawlists[GLDL_FOGMASKED].Sort();
gl_drawinfo->drawlists[GLDL_FOGMASKED].Draw(gl_texture? GLPASS_PLAIN : GLPASS_BASE_MASKED);
gl_drawinfo->drawlists[GLDL_FOGMASKED].Draw(pass);
gl_drawinfo->drawlists[GLDL_LIGHTFOGMASKED].Sort();
gl_drawinfo->drawlists[GLDL_LIGHTFOGMASKED].Draw(gl_texture? GLPASS_PLAIN : GLPASS_BASE_MASKED);
gl_drawinfo->drawlists[GLDL_LIGHTFOGMASKED].Draw(pass);
// And now the multipass stuff
if (!gl_dynlight_shader)
if (!gl_dynlight_shader && gl_lights)
{
// First pass: empty background with sector light only
@ -399,7 +415,7 @@ void FGLRenderer::RenderScene(int recursion)
// second pass: draw lights (on fogged surfaces they are added to the textures!)
gl.DepthMask(false);
if (gl_lights && mLightCount && !gl_fixedcolormap)
if (mLightCount && !gl_fixedcolormap)
{
if (gl_SetupLightTexture())
{

View file

@ -97,11 +97,12 @@ void gl_SetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblend
//==========================================================================
void GLSprite::Draw(int pass)
{
if (pass!=GLPASS_PLAIN && pass != GLPASS_ALL && pass!=GLPASS_TRANSLUCENT) return;
bool additivefog = false;
int rel = extralight*gl_weaponlight;
if (pass!=GLPASS_PLAIN && pass!=GLPASS_TRANSLUCENT) return;
if (pass==GLPASS_TRANSLUCENT)
{
// The translucent pass requires special setup for the various modes.

View file

@ -196,7 +196,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, !!(flags&GLWF_FOGGY), lightdata);
gl_GetLight(p, node->lightsource, Colormap.colormap, true, false, lightdata);
}
}
}
@ -296,6 +296,7 @@ void GLWall::RenderFogBoundary()
{
if (gl_fogmode && gl_fixedcolormap == 0)
{
// with shaders this can be done properly
if (gl.shadermodel == 4 || (gl.shadermodel == 3 && gl_fog_shader))
{
int rel = rellight + (extralight * gl_weaponlight);
@ -308,6 +309,8 @@ void GLWall::RenderFogBoundary()
}
else
{
// otherwise some approximation is needed. This won't look as good
// as the shader version but it's an acceptable compromise.
float fogdensity=gl_GetFogDensity(lightlevel, Colormap.FadeColor);
float xcamera=TO_GL(viewx);
@ -351,6 +354,7 @@ void GLWall::RenderMirrorSurface()
{
if (GLRenderer->mirrortexture == NULL) return;
// For the sphere map effect we need a normal of the mirror surface,
Vector v(glseg.y2-glseg.y1, 0 ,-glseg.x2+glseg.x1);
v.Normalize();
glNormal3fv(&v[0]);
@ -474,36 +478,37 @@ void GLWall::Draw(int pass)
switch (pass)
{
case GLPASS_ALL: // Single-pass rendering
SetupLights();
// fall through
case GLPASS_PLAIN: // Single-pass rendering
if (gl_dynlight_shader && GLRenderer->mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT)
{
SetupLights();
}
case GLPASS_BASE: // Base pass for non-masked polygons (all opaque geometry)
case GLPASS_BASE_MASKED: // Base pass for masked polygons (2sided mid-textures and transparent 3D floors)
rel = rellight + (extralight * gl_weaponlight);
gl_SetColor(lightlevel, rel, &Colormap,1.0f);
if (!(flags&GLWF_FOGGY) || pass == GLPASS_PLAIN)
if (!(flags&GLWF_FOGGY) || pass == GLPASS_PLAIN || pass == GLPASS_ALL)
{
if (type!=RENDERWALL_M2SNF) gl_SetFog(lightlevel, rel, &Colormap, false);
else gl_SetFog(255, 0, NULL, false);
}
gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW));
// fall through
case GLPASS_TEXTURE: // modulated texture
if (pass != GLPASS_BASE)
{
gltexture->Bind(Colormap.colormap, flags, 0);
}
RenderWall((pass!=GLPASS_BASE) + 2*(pass!=GLPASS_TEXTURE), NULL);
RenderWall(pass == GLPASS_BASE? 2:3, NULL);
gl_RenderState.EnableGlow(false);
gl_RenderState.EnableLight(false);
break;
case GLPASS_TEXTURE: // modulated texture
gltexture->Bind(Colormap.colormap, flags, 0);
RenderWall(1, NULL);
break;
case GLPASS_LIGHT:
case GLPASS_LIGHT_ADDITIVE:
// black fog is diminishing light and should affect lights less than the rest!