- draw texture based dynamic lights on walls.

This commit is contained in:
Christoph Oelckers 2016-05-05 12:18:09 +02:00
parent 2b92048a5b
commit d61ec05c0f
4 changed files with 70 additions and 15 deletions

View file

@ -68,8 +68,7 @@ void gl_PatchMenu()
{ {
if (gl.glslversion == 0) if (gl.glslversion == 0)
{ {
// Radial fog and Doom lighting are not available in SM < 4 cards // Radial fog and Doom lighting are not available without full shader support.
// The way they are implemented does not work well on older hardware.
FOptionValues **opt = OptionValues.CheckKey("LightingModes"); FOptionValues **opt = OptionValues.CheckKey("LightingModes");
if (opt != NULL) if (opt != NULL)
@ -443,7 +442,7 @@ bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, Vector & nearPt,
g = (g*(32 - desaturation) + gray*desaturation) / 32; g = (g*(32 - desaturation) + gray*desaturation) / 32;
b = (b*(32 - desaturation) + gray*desaturation) / 32; b = (b*(32 - desaturation) + gray*desaturation) / 32;
} }
glColor3f(r, g, b); gl_RenderState.SetColor(r, g, b);
return true; return true;
} }
@ -457,7 +456,7 @@ bool gl_SetupLightTexture()
{ {
if (GLRenderer->gllight == nullptr) return false; if (GLRenderer->gllight == nullptr) return false;
FMaterial * pat = FMaterial::ValidateTexture(GLRenderer->gllight, false); FMaterial * pat = FMaterial::ValidateTexture(GLRenderer->gllight, false);
pat->Bind(CLAMP_XY, 0); pat->Bind(CLAMP_XY_NOMIP, 0);
return true; return true;
} }
@ -488,7 +487,7 @@ bool GLWall::PutWallCompat(int passflag)
if (sub->lighthead != nullptr) return false; if (sub->lighthead != nullptr) return false;
} }
bool foggy = (!gl_isBlack(Colormap.FadeColor) || level.flags&LEVEL_HASFADETABLE); bool foggy = !gl_isBlack(Colormap.FadeColor) || (level.flags&LEVEL_HASFADETABLE) || gl_lights_additive;
bool masked = passflag == 2 && gltexture->isMasked(); bool masked = passflag == 2 && gltexture->isMasked();
int list = list_indices[masked][foggy]; int list = list_indices[masked][foggy];
@ -517,7 +516,7 @@ bool GLFlat::PutFlatCompat(bool fog)
{ { GLLDL_FLATS_PLAIN, GLLDL_FLATS_FOG },{ GLLDL_FLATS_MASKED, GLLDL_FLATS_FOGMASKED } }; { { GLLDL_FLATS_PLAIN, GLLDL_FLATS_FOG },{ GLLDL_FLATS_MASKED, GLLDL_FLATS_FOGMASKED } };
bool masked = gltexture->isMasked() && ((renderflags&SSRF_RENDER3DPLANES) || stack); bool masked = gltexture->isMasked() && ((renderflags&SSRF_RENDER3DPLANES) || stack);
bool foggy = gl_CheckFog(&Colormap, lightlevel) || level.flags&LEVEL_HASFADETABLE; bool foggy = gl_CheckFog(&Colormap, lightlevel) || (level.flags&LEVEL_HASFADETABLE) || gl_lights_additive;
int list = list_indices[masked][foggy]; int list = list_indices[masked][foggy];
@ -591,7 +590,6 @@ void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass)
float scale; float scale;
FLightNode * node = sub->lighthead; FLightNode * node = sub->lighthead;
gl_RenderState.Apply();
while (node) while (node)
{ {
ADynamicLight * light = node->lightsource; ADynamicLight * light = node->lightsource;
@ -614,11 +612,12 @@ void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass)
} }
p.Set(plane.plane); p.Set(plane.plane);
if (!gl_SetupLight(sub->sector->PortalGroup, p, light, nearPt, up, right, scale, CM_DEFAULT, false, pass == GLPASS_LIGHTTEX_ADDITIVE)) if (!gl_SetupLight(sub->sector->PortalGroup, p, light, nearPt, up, right, scale, CM_DEFAULT, false, pass != GLPASS_LIGHTTEX))
{ {
node = node->nextLight; node = node->nextLight;
continue; continue;
} }
gl_RenderState.Apply();
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
for (unsigned int k = 0; k < sub->numlines; k++) for (unsigned int k = 0; k < sub->numlines; k++)
@ -687,7 +686,7 @@ void GLFlat::DrawLightsCompat(int pass)
// Sets up the texture coordinates for one light to be rendered // Sets up the texture coordinates for one light to be rendered
// //
//========================================================================== //==========================================================================
bool GLWall::PrepareLight(texcoord * tcs, ADynamicLight * light, int pass) bool GLWall::PrepareLight(ADynamicLight * light, int pass)
{ {
float vtx[] = { glseg.x1,zbottom[0],glseg.y1, glseg.x1,ztop[0],glseg.y1, glseg.x2,ztop[1],glseg.y2, glseg.x2,zbottom[1],glseg.y2 }; float vtx[] = { glseg.x1,zbottom[0],glseg.y1, glseg.x1,ztop[0],glseg.y1, glseg.x2,ztop[1],glseg.y2, glseg.x2,zbottom[1],glseg.y2 };
Plane p; Plane p;
@ -701,7 +700,7 @@ bool GLWall::PrepareLight(texcoord * tcs, ADynamicLight * light, int pass)
return false; return false;
} }
if (!gl_SetupLight(seg->frontsector->PortalGroup, p, light, nearPt, up, right, scale, CM_DEFAULT, true, pass == GLPASS_LIGHTTEX_ADDITIVE)) if (!gl_SetupLight(seg->frontsector->PortalGroup, p, light, nearPt, up, right, scale, CM_DEFAULT, true, pass != GLPASS_LIGHTTEX))
{ {
return false; return false;
} }
@ -734,6 +733,55 @@ bool GLWall::PrepareLight(texcoord * tcs, ADynamicLight * light, int pass)
} }
void GLWall::RenderLightsCompat(int pass)
{
FLightNode * node;
// black fog is diminishing light and should affect lights less than the rest!
if (pass == GLPASS_LIGHTTEX) gl_SetFog((255 + lightlevel) >> 1, 0, NULL, false);
else gl_SetFog(lightlevel, 0, &Colormap, true);
if (seg->sidedef == NULL)
{
return;
}
else if (!(seg->sidedef->Flags & WALLF_POLYOBJ))
{
// Iterate through all dynamic lights which touch this wall and render them
node = seg->sidedef->lighthead;
}
else if (sub)
{
// To avoid constant rechecking for polyobjects use the subsector's lightlist instead
node = sub->lighthead;
}
else
{
return;
}
texcoord save[4];
memcpy(save, tcs, sizeof(tcs));
while (node)
{
ADynamicLight * light = node->lightsource;
if (light->flags2&MF2_DORMANT ||
(pass == GLPASS_LIGHTTEX && light->IsAdditive()) ||
(pass == GLPASS_LIGHTTEX_ADDITIVE && !light->IsAdditive()))
{
node = node->nextLight;
continue;
}
if (PrepareLight(light, pass))
{
RenderWall(RWF_TEXTURED, NULL);
}
node = node->nextLight;
}
memcpy(tcs, save, sizeof(tcs));
}
//========================================================================== //==========================================================================
// //
// //
@ -820,10 +868,10 @@ void FGLRenderer::RenderMultipassStuff()
gl_drawinfo->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(GLPASS_LIGHTTEX_ADDITIVE); gl_drawinfo->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(GLPASS_LIGHTTEX_ADDITIVE);
gl_drawinfo->dldrawlists[GLLDL_FLATS_BRIGHT].DrawFlats(GLPASS_LIGHTTEX_ADDITIVE); gl_drawinfo->dldrawlists[GLLDL_FLATS_BRIGHT].DrawFlats(GLPASS_LIGHTTEX_ADDITIVE);
gl_drawinfo->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(GLPASS_LIGHTTEX_ADDITIVE); gl_drawinfo->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(GLPASS_LIGHTTEX_ADDITIVE);
gl_drawinfo->dldrawlists[GLLDL_WALLS_FOG].DrawWalls(GLPASS_LIGHTTEX_ADDITIVE); gl_drawinfo->dldrawlists[GLLDL_WALLS_FOG].DrawWalls(GLPASS_LIGHTTEX_FOGGY);
gl_drawinfo->dldrawlists[GLLDL_WALLS_FOGMASKED].DrawWalls(GLPASS_LIGHTTEX_ADDITIVE); gl_drawinfo->dldrawlists[GLLDL_WALLS_FOGMASKED].DrawWalls(GLPASS_LIGHTTEX_FOGGY);
gl_drawinfo->dldrawlists[GLLDL_FLATS_FOG].DrawFlats(GLPASS_LIGHTTEX_ADDITIVE); gl_drawinfo->dldrawlists[GLLDL_FLATS_FOG].DrawFlats(GLPASS_LIGHTTEX_FOGGY);
gl_drawinfo->dldrawlists[GLLDL_FLATS_FOGMASKED].DrawFlats(GLPASS_LIGHTTEX_ADDITIVE); gl_drawinfo->dldrawlists[GLLDL_FLATS_FOGMASKED].DrawFlats(GLPASS_LIGHTTEX_FOGGY);
} }
else gl_lights = false; else gl_lights = false;

View file

@ -61,6 +61,7 @@ enum Drawpasses
GLPASS_LIGHTTEX, // lighttexture pass GLPASS_LIGHTTEX, // lighttexture pass
GLPASS_TEXONLY, // finishing texture pass GLPASS_TEXONLY, // finishing texture pass
GLPASS_LIGHTTEX_ADDITIVE, // lighttexture pass (additive) GLPASS_LIGHTTEX_ADDITIVE, // lighttexture pass (additive)
GLPASS_LIGHTTEX_FOGGY, // lighttexture pass on foggy surfaces (forces all lights to be additive)
}; };

View file

@ -184,13 +184,14 @@ private:
void CheckTexturePosition(); void CheckTexturePosition();
void RenderFogBoundaryCompat(); void RenderFogBoundaryCompat();
void RenderLightsCompat(int pass);
void Put3DWall(lightlist_t * lightlist, bool translucent); void Put3DWall(lightlist_t * lightlist, bool translucent);
void SplitWallComplex(sector_t * frontsector, bool translucent, float maplightbottomleft, float maplightbottomright); void SplitWallComplex(sector_t * frontsector, bool translucent, float maplightbottomleft, float maplightbottomright);
void SplitWall(sector_t * frontsector, bool translucent); void SplitWall(sector_t * frontsector, bool translucent);
void SetupLights(); void SetupLights();
bool PrepareLight(texcoord * tcs, ADynamicLight * light, int pass); bool PrepareLight(ADynamicLight * light, int pass);
void RenderWall(int textured, unsigned int *store = NULL); void RenderWall(int textured, unsigned int *store = NULL);
void RenderTextured(int rflags); void RenderTextured(int rflags);

View file

@ -442,5 +442,10 @@ void GLWall::Draw(int pass)
RenderTranslucentWall(); RenderTranslucentWall();
break; break;
} }
case GLPASS_LIGHTTEX:
case GLPASS_LIGHTTEX_ADDITIVE:
RenderLightsCompat(pass);
break;
} }
} }