- made wall draw code API independent.

This commit is contained in:
Christoph Oelckers 2018-10-21 13:53:50 +02:00
parent 7897f26abf
commit 8ffeb7812f
12 changed files with 275 additions and 264 deletions

View File

@ -209,8 +209,6 @@ void FDrawInfo::StartScene()
outer = gl_drawinfo;
gl_drawinfo = this;
for (int i = 0; i < GLDL_TYPES; i++) drawlists[i].Reset();
decals[0].Clear();
decals[1].Clear();
hudsprites.Clear();
vpIndex = 0;
@ -256,13 +254,6 @@ std::pair<FFlatVertex *, unsigned int> FDrawInfo::AllocVertices(unsigned int cou
return std::make_pair(p, index);
}
GLDecal *FDrawInfo::AddDecal(bool onmirror)
{
auto decal = (GLDecal*)RenderDataAllocator.Alloc(sizeof(GLDecal));
decals[onmirror ? 1 : 0].Push(decal);
return decal;
}
int FDrawInfo::UploadLights(FDynLightData &data)
{
return GLRenderer->mLights->UploadLights(data);
@ -312,6 +303,12 @@ void FDrawInfo::SetDepthMask(bool on)
glDepthMask(on);
}
void FDrawInfo::SetDepthFunc(int func)
{
static int df2gl[] = { GL_LESS, GL_LEQUAL, GL_ALWAYS };
glDepthFunc(df2gl[func]);
}
void FDrawInfo::EnableDrawBufferAttachments(bool on)
{
gl_RenderState.EnableDrawBuffers(on? gl_RenderState.GetPassDrawBufferCount() : 1);

View File

@ -30,7 +30,6 @@ enum DrawListType
enum Drawpasses
{
GLPASS_ALL, // Main pass with dynamic lights
GLPASS_DECALS, // Draws a decal
GLPASS_TRANSLUCENT, // Draws translucent objects
};
@ -38,14 +37,12 @@ struct FDrawInfo : public HWDrawInfo
{
HWDrawList drawlists[GLDL_TYPES];
TArray<HUDSprite> hudsprites; // These may just be stored by value.
TArray<GLDecal *> decals[2]; // the second slot is for mirrors which get rendered in a separate pass.
int vpIndex;
void ApplyVPUniforms() override;
void AddWall(GLWall *wall) override;
void AddMirrorSurface(GLWall *w) override;
GLDecal *AddDecal(bool onmirror) override;
void AddPortal(GLWall *w, int portaltype) override;
void AddFlat(GLFlat *flat, bool fog) override;
void AddSprite(GLSprite *sprite, bool translucent) override;
@ -57,18 +54,11 @@ struct FDrawInfo : public HWDrawInfo
void Draw(EDrawType dt, FRenderState &state, int index, int count, bool apply = true) override;
void DrawIndexed(EDrawType dt, FRenderState &state, int index, int count, bool apply = true) override;
void SetDepthMask(bool on) override;
void SetDepthFunc(int func) override;
void EnableDrawBufferAttachments(bool on) override;
void StartScene();
// Wall drawer
void RenderWall(GLWall *wall, FRenderState &state, int textured);
void RenderFogBoundary(GLWall *wall, FRenderState &state);
void RenderMirrorSurface(GLWall *wall, FRenderState &state);
void RenderTranslucentWall(GLWall *wall, FRenderState &state);
void RenderTexturedWall(GLWall *wall, FRenderState &state, int rflags);
void DrawWall(GLWall *wall, int pass) override;
// Sprite drawer
void DrawSprite(GLSprite *sprite, int pass);
void DrawPSprite(HUDSprite *huds);

View File

@ -173,7 +173,7 @@ void FDrawInfo::RenderScene(int recursion)
gl_RenderState.EnableTexture(gl_texture);
gl_RenderState.EnableBrightmap(true);
drawlists[GLDL_PLAINWALLS].DrawWalls(this, pass);
drawlists[GLDL_PLAINWALLS].DrawWalls(this, gl_RenderState, false);
drawlists[GLDL_PLAINFLATS].DrawFlats(this, gl_RenderState, false);
@ -184,17 +184,15 @@ void FDrawInfo::RenderScene(int recursion)
gl_RenderState.SetTextureMode(TM_STENCIL);
}
gl_RenderState.AlphaFunc(Alpha_GEqual, gl_mask_threshold);
drawlists[GLDL_MASKEDWALLS].DrawWalls(this, pass);
drawlists[GLDL_MASKEDWALLS].DrawWalls(this, gl_RenderState, false);
drawlists[GLDL_MASKEDFLATS].DrawFlats(this, gl_RenderState, false);
// Part 3: masked geometry with polygon offset. This list is empty most of the time so only waste time on it when in use.
if (drawlists[GLDL_MASKEDWALLSOFS].Size() > 0)
{
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(-1.0f, -128.0f);
drawlists[GLDL_MASKEDWALLSOFS].DrawWalls(this, pass);
glDisable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(0, 0);
gl_RenderState.SetDepthBias(-1, -128);
drawlists[GLDL_MASKEDWALLSOFS].DrawWalls(this, gl_RenderState, false);
gl_RenderState.ClearDepthBias();
}
drawlists[GLDL_MODELS].Draw(this, gl_RenderState, false, pass);
@ -203,10 +201,8 @@ void FDrawInfo::RenderScene(int recursion)
// Part 4: Draw decals (not a real pass)
glDepthFunc(GL_LEQUAL);
glDepthMask(false);
DrawDecals(gl_RenderState, decals[0]);
DrawDecals(gl_RenderState, Decals[0]);
glDepthMask(true);
RenderAll.Unclock();
}

View File

@ -70,8 +70,6 @@ void gl_SetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblend
void FDrawInfo::DrawSprite(GLSprite *sprite, int pass)
{
if (pass == GLPASS_DECALS) return;
auto RenderStyle = sprite->RenderStyle;
bool additivefog = false;

View File

@ -40,231 +40,6 @@
EXTERN_CVAR(Bool, gl_seamless)
//==========================================================================
//
// General purpose wall rendering function
// everything goes through here
//
//==========================================================================
void FDrawInfo::RenderWall(GLWall *wall, FRenderState &state, int textured)
{
assert(wall->vertcount > 0);
state.SetLightIndex(wall->dynlightindex);
Draw(DT_TriangleFan, gl_RenderState, wall->vertindex, wall->vertcount);
vertexcount += wall->vertcount;
}
//==========================================================================
//
//
//
//==========================================================================
void FDrawInfo::RenderFogBoundary(GLWall *wall, FRenderState &state)
{
if (gl_fogmode && !isFullbrightScene())
{
int rel = wall->rellight + getExtraLight();
EnableDrawBufferAttachments(false);
state.SetFog(wall->lightlevel, rel, false, &wall->Colormap, false);
state.SetEffect(EFF_FOGBOUNDARY);
state.AlphaFunc(Alpha_GEqual, 0.f);
state.SetDepthBias(-1, -128);
RenderWall(wall, state, GLWall::RWF_BLANK);
state.ClearDepthBias();
state.SetEffect(EFF_NONE);
EnableDrawBufferAttachments(true);
}
}
//==========================================================================
//
//
//
//==========================================================================
void FDrawInfo::RenderMirrorSurface(GLWall *wall, FRenderState &state)
{
if (!TexMan.mirrorTexture.isValid()) return;
// we use texture coordinates and texture matrix to pass the normal stuff to the shader so that the default vertex buffer format can be used as is.
state.EnableTextureMatrix(true);
// Use sphere mapping for this
state.SetEffect(EFF_SPHEREMAP);
state.SetColor(wall->lightlevel, 0, isFullbrightScene(), wall->Colormap ,0.1f);
state.SetFog(wall->lightlevel, 0, isFullbrightScene(), &wall->Colormap, true);
state.SetRenderStyle(STYLE_Add);
state.AlphaFunc(Alpha_Greater,0);
glDepthFunc(GL_LEQUAL);
FMaterial * pat=FMaterial::ValidateTexture(TexMan.mirrorTexture, false, false);
gl_RenderState.ApplyMaterial(pat, CLAMP_NONE, 0, -1);
wall->flags &= ~GLWall::GLWF_GLOW;
RenderWall(wall, state, GLWall::RWF_BLANK);
state.EnableTextureMatrix(false);
state.SetEffect(EFF_NONE);
// Restore the defaults for the translucent pass
state.AlphaFunc(Alpha_GEqual, gl_mask_sprite_threshold);
glDepthFunc(GL_LESS);
// This is drawn in the translucent pass which is done after the decal pass
// As a result the decals have to be drawn here, right after the wall they are on,
// because the depth buffer won't get set by translucent items.
if (wall->seg->sidedef->AttachedDecals)
{
wall->DrawDecalsForMirror(this, gl_RenderState, decals[1]);
}
state.SetRenderStyle(STYLE_Translucent);
}
//==========================================================================
//
//
//
//==========================================================================
void FDrawInfo::RenderTexturedWall(GLWall *wall, FRenderState &state, int rflags)
{
int tmode = state.GetTextureMode();
int rel = wall->rellight + getExtraLight();
if (wall->flags & GLWall::GLWF_GLOW)
{
state.EnableGlow(true);
state.SetGlowParams(wall->topglowcolor, wall->bottomglowcolor);
}
state.SetGlowPlanes(wall->topplane, wall->bottomplane);
state.SetMaterial(wall->gltexture, wall->flags & 3, 0, -1);
if (wall->type == RENDERWALL_M2SNF)
{
if (wall->flags & GLWall::GLWF_CLAMPY)
{
if (tmode == TM_NORMAL) state.SetTextureMode(TM_CLAMPY);
}
SetFog(255, 0, nullptr, false);
}
state.SetObjectColor(wall->seg->frontsector->SpecialColors[sector_t::walltop] | 0xff000000);
state.SetObjectColor2(wall->seg->frontsector->SpecialColors[sector_t::wallbottom] | 0xff000000);
float absalpha = fabsf(wall->alpha);
if (wall->lightlist == nullptr)
{
if (wall->type != RENDERWALL_M2SNF) SetFog(wall->lightlevel, rel, &wall->Colormap, wall->RenderStyle == STYLE_Add);
SetColor(wall->lightlevel, rel, wall->Colormap, absalpha);
RenderWall(wall, state, rflags);
}
else
{
state.EnableSplit(true);
for (unsigned i = 0; i < wall->lightlist->Size(); i++)
{
secplane_t &lowplane = i == (*wall->lightlist).Size() - 1 ? wall->bottomplane : (*wall->lightlist)[i + 1].plane;
// this must use the exact same calculation method as GLWall::Process etc.
float low1 = lowplane.ZatPoint(wall->vertexes[0]);
float low2 = lowplane.ZatPoint(wall->vertexes[1]);
if (low1 < wall->ztop[0] || low2 < wall->ztop[1])
{
int thisll = (*wall->lightlist)[i].caster != NULL ? hw_ClampLight(*(*wall->lightlist)[i].p_lightlevel) : wall->lightlevel;
FColormap thiscm;
thiscm.FadeColor = wall->Colormap.FadeColor;
thiscm.FogDensity = wall->Colormap.FogDensity;
thiscm.CopyFrom3DLight(&(*wall->lightlist)[i]);
state.SetColor(thisll, rel, false, thiscm, absalpha);
if (wall->type != RENDERWALL_M2SNF) state.SetFog(thisll, rel, false, &thiscm, wall->RenderStyle == STYLE_Add);
state.SetSplitPlanes((*wall->lightlist)[i].plane, lowplane);
RenderWall(wall, state, rflags);
}
if (low1 <= wall->zbottom[0] && low2 <= wall->zbottom[1]) break;
}
state.EnableSplit(false);
}
state.SetObjectColor(0xffffffff);
state.SetObjectColor2(0);
state.SetTextureMode(tmode);
state.EnableGlow(false);
}
//==========================================================================
//
//
//
//==========================================================================
void FDrawInfo::RenderTranslucentWall(GLWall *wall, FRenderState &state)
{
state.SetRenderStyle(wall->RenderStyle);
if (wall->gltexture)
{
if (!wall->gltexture->tex->GetTranslucency()) state.AlphaFunc(Alpha_GEqual, gl_mask_threshold);
else state.AlphaFunc(Alpha_GEqual, 0.f);
RenderTexturedWall(wall, state, GLWall::RWF_TEXTURED | GLWall::RWF_NOSPLIT);
}
else
{
state.AlphaFunc(Alpha_GEqual, 0.f);
state.SetColor(wall->lightlevel, 0, false, wall->Colormap, fabsf(wall->alpha));
state.SetFog(wall->lightlevel, 0, false, &wall->Colormap, wall->RenderStyle == STYLE_Add);
state.EnableTexture(false);
RenderWall(wall, state, GLWall::RWF_NOSPLIT);
state.EnableTexture(true);
}
state.SetRenderStyle(STYLE_Translucent);
}
//==========================================================================
//
//
//
//==========================================================================
void FDrawInfo::DrawWall(GLWall *wall, int pass)
{
FRenderState &state = gl_RenderState;
if (screen->BuffersArePersistent())
{
if (level.HasDynamicLights && !isFullbrightScene() && wall->gltexture != nullptr)
{
wall->SetupLights(this, lightdata);
}
wall->MakeVertices(this, !!(wall->flags & GLWall::GLWF_TRANSLUCENT));
}
gl_RenderState.SetNormal(wall->glseg.Normal());
switch (pass)
{
case GLPASS_ALL:
RenderTexturedWall(wall, state, GLWall::RWF_TEXTURED);
break;
case GLPASS_TRANSLUCENT:
switch (wall->type)
{
case RENDERWALL_MIRRORSURFACE:
RenderMirrorSurface(wall, state);
break;
case RENDERWALL_FOGBOUNDARY:
RenderFogBoundary(wall, state);
break;
default:
RenderTranslucentWall(wall, state);
break;
}
break;
}
}
//==========================================================================
//
//

View File

@ -132,6 +132,7 @@ void GLDecal::DrawDecal(HWDrawInfo *di, FRenderState &state)
void HWDrawInfo::DrawDecals(FRenderState &state, TArray<GLDecal *> &decals)
{
side_t *wall = nullptr;
SetDepthMask(false);
state.SetDepthBias(-1, -128);
for (auto gldecal : decals)
{
@ -153,6 +154,7 @@ void HWDrawInfo::DrawDecals(FRenderState &state, TArray<GLDecal *> &decals)
state.EnableSplit(false);
state.ClearDepthBias();
state.SetTextureMode(TM_NORMAL);
SetDepthMask(true);
}
//==========================================================================

View File

@ -33,6 +33,7 @@
#include "hw_fakeflat.h"
#include "hw_drawinfo.h"
#include "hw_portal.h"
#include "hw_drawlist.h"
#include "hwrenderer/utility/hw_clock.h"
#include "hwrenderer/utility/hw_cvars.h"
@ -94,6 +95,9 @@ void HWDrawInfo::ClearBuffers()
memset(&ss_renderflags[0], 0, level.subsectors.Size() * sizeof(ss_renderflags[0]));
memset(&no_renderflags[0], 0, level.nodes.Size() * sizeof(no_renderflags[0]));
Decals[0].Clear();
Decals[1].Clear();
mClipPortal = nullptr;
mCurrentPortal = nullptr;
}
@ -282,3 +286,17 @@ void HWViewpointUniforms::SetDefaults()
mShadowmapFilter = gl_shadowmap_filter;
}
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
GLDecal *HWDrawInfo::AddDecal(bool onmirror)
{
auto decal = (GLDecal*)RenderDataAllocator.Alloc(sizeof(GLDecal));
Decals[onmirror ? 1 : 0].Push(decal);
return decal;
}

View File

@ -16,6 +16,13 @@ enum EDrawType
DT_TriangleStrip = 4
};
enum EDepthFunc
{
DF_Less,
DF_LEqual,
DF_Always
};
struct FSectorPortalGroup;
struct FLinePortalSpan;
struct FFlatVertex;
@ -130,6 +137,7 @@ struct HWDrawInfo
FRenderViewpoint Viewpoint;
HWViewpointUniforms VPUniforms; // per-viewpoint uniform state
TArray<IPortal *> Portals;
TArray<GLDecal *> Decals[2]; // the second slot is for mirrors which get rendered in a separate pass.
TArray<MissingTextureInfo> MissingUpperTextures;
TArray<MissingTextureInfo> MissingLowerTextures;
@ -286,7 +294,6 @@ public:
void DrawDecals(FRenderState &state, TArray<GLDecal *> &decals);
virtual void DrawWall(GLWall *wall, int pass) = 0;
virtual void DrawSprite(GLSprite *sprite, int pass) = 0;
void ProcessLowerMinisegs(TArray<seg_t *> &lowersegs);
@ -303,7 +310,7 @@ public:
virtual void ApplyVPUniforms() = 0;
virtual bool SetDepthClamp(bool on) = 0;
virtual GLDecal *AddDecal(bool onmirror) = 0;
GLDecal *AddDecal(bool onmirror);
virtual std::pair<FFlatVertex *, unsigned int> AllocVertices(unsigned int count) = 0;
virtual void Draw(EDrawType dt, FRenderState &state, int index, int count, bool apply = true) = 0;
@ -311,6 +318,7 @@ public:
// Immediate render state change commands. These only change infrequently and should not clutter the render state.
virtual void SetDepthMask(bool on) = 0;
virtual void SetDepthFunc(int func) = 0;
virtual void EnableDrawBufferAttachments(bool on) = 0;
};

View File

@ -788,7 +788,7 @@ void HWDrawList::DoDraw(HWDrawInfo *di, FRenderState &state, bool translucent, i
{
GLWall * w= walls[drawitems[i].index];
RenderWall.Clock();
di->DrawWall(w, pass);
w->DrawWall(di, state, translucent);
RenderWall.Unclock();
}
break;
@ -822,12 +822,12 @@ void HWDrawList::Draw(HWDrawInfo *di, FRenderState &state, bool translucent, int
//
//
//==========================================================================
void HWDrawList::DrawWalls(HWDrawInfo *di, int pass)
void HWDrawList::DrawWalls(HWDrawInfo *di, FRenderState &state, bool translucent)
{
RenderWall.Clock();
for (auto &item : drawitems)
{
di->DrawWall(walls[item.index], pass);
walls[item.index]->DrawWall(di, state, translucent);
}
RenderWall.Unclock();
}

View File

@ -105,7 +105,7 @@ public:
void DoDraw(HWDrawInfo *di, FRenderState &state, bool translucent, int pass, int i, bool trans);
void Draw(HWDrawInfo *di, FRenderState &state, bool translucent, int pass, bool trans = false);
void DrawWalls(HWDrawInfo *di, int pass);
void DrawWalls(HWDrawInfo *di, FRenderState &state, bool translucent);
void DrawFlats(HWDrawInfo *di, FRenderState &state, bool translucent);
HWDrawList * next;

View File

@ -263,6 +263,13 @@ public:
int CountVertices();
void RenderWall(HWDrawInfo *di, FRenderState &state, int textured);
void RenderFogBoundary(HWDrawInfo *di, FRenderState &state);
void RenderMirrorSurface(HWDrawInfo *di, FRenderState &state);
void RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags);
void RenderTranslucentWall(HWDrawInfo *di, FRenderState &state);
void DrawDecalsForMirror(HWDrawInfo *di, FRenderState &state, TArray<GLDecal *> &decals);
public:
GLWall() {}
@ -285,7 +292,7 @@ public:
return -((y-glseg.y1)*(glseg.x2-glseg.x1)-(x-glseg.x1)*(glseg.y2-glseg.y1));
}
void DrawDecalsForMirror(HWDrawInfo *di, FRenderState &state, TArray<GLDecal *> &decals);
void DrawWall(HWDrawInfo *di, FRenderState &state, bool translucent);
};

View File

@ -38,7 +38,227 @@
#include "hwrenderer/scene/hw_drawinfo.h"
#include "hwrenderer/scene/hw_drawstructs.h"
#include "hwrenderer/scene/hw_portal.h"
#include "hw_renderstate.h"
//==========================================================================
//
// General purpose wall rendering function
// everything goes through here
//
//==========================================================================
void GLWall::RenderWall(HWDrawInfo *di, FRenderState &state, int textured)
{
assert(vertcount > 0);
state.SetLightIndex(dynlightindex);
di->Draw(DT_TriangleFan, state, vertindex, vertcount);
vertexcount += vertcount;
}
//==========================================================================
//
//
//
//==========================================================================
void GLWall::RenderFogBoundary(HWDrawInfo *di, FRenderState &state)
{
if (gl_fogmode && !di->isFullbrightScene())
{
int rel = rellight + getExtraLight();
di->EnableDrawBufferAttachments(false);
state.SetFog(lightlevel, rel, false, &Colormap, false);
state.SetEffect(EFF_FOGBOUNDARY);
state.AlphaFunc(Alpha_GEqual, 0.f);
state.SetDepthBias(-1, -128);
RenderWall(di, state, GLWall::RWF_BLANK);
state.ClearDepthBias();
state.SetEffect(EFF_NONE);
di->EnableDrawBufferAttachments(true);
}
}
//==========================================================================
//
//
//
//==========================================================================
void GLWall::RenderMirrorSurface(HWDrawInfo *di, FRenderState &state)
{
if (!TexMan.mirrorTexture.isValid()) return;
di->SetDepthFunc(DF_LEqual);
// we use texture coordinates and texture matrix to pass the normal stuff to the shader so that the default vertex buffer format can be used as is.
state.EnableTextureMatrix(true);
// Use sphere mapping for this
state.SetEffect(EFF_SPHEREMAP);
state.SetColor(lightlevel, 0, di->isFullbrightScene(), Colormap, 0.1f);
state.SetFog(lightlevel, 0, di->isFullbrightScene(), &Colormap, true);
state.SetRenderStyle(STYLE_Add);
state.AlphaFunc(Alpha_Greater, 0);
FMaterial * pat = FMaterial::ValidateTexture(TexMan.mirrorTexture, false, false);
state.SetMaterial(pat, CLAMP_NONE, 0, -1);
flags &= ~GLWall::GLWF_GLOW;
RenderWall(di, state, GLWall::RWF_BLANK);
state.EnableTextureMatrix(false);
state.SetEffect(EFF_NONE);
state.AlphaFunc(Alpha_GEqual, gl_mask_sprite_threshold);
di->SetDepthFunc(DF_Less);
// This is drawn in the translucent pass which is done after the decal pass
// As a result the decals have to be drawn here, right after the wall they are on,
// because the depth buffer won't get set by translucent items.
if (seg->sidedef->AttachedDecals)
{
DrawDecalsForMirror(di, state, di->Decals[1]);
}
state.SetRenderStyle(STYLE_Translucent);
}
//==========================================================================
//
//
//
//==========================================================================
void GLWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags)
{
int tmode = state.GetTextureMode();
int rel = rellight + getExtraLight();
if (flags & GLWall::GLWF_GLOW)
{
state.EnableGlow(true);
state.SetGlowParams(topglowcolor, bottomglowcolor);
}
state.SetGlowPlanes(topplane, bottomplane);
state.SetMaterial(gltexture, flags & 3, 0, -1);
if (type == RENDERWALL_M2SNF)
{
if (flags & GLWall::GLWF_CLAMPY)
{
if (tmode == TM_NORMAL) state.SetTextureMode(TM_CLAMPY);
}
state.SetFog(255, 0, di->isFullbrightScene(), nullptr, false);
}
state.SetObjectColor(seg->frontsector->SpecialColors[sector_t::walltop] | 0xff000000);
state.SetObjectColor2(seg->frontsector->SpecialColors[sector_t::wallbottom] | 0xff000000);
float absalpha = fabsf(alpha);
if (lightlist == nullptr)
{
if (type != RENDERWALL_M2SNF) state.SetFog(lightlevel, rel, di->isFullbrightScene(), &Colormap, RenderStyle == STYLE_Add);
state.SetColor(lightlevel, rel, di->isFullbrightScene(), Colormap, absalpha);
RenderWall(di, state, rflags);
}
else
{
state.EnableSplit(true);
for (unsigned i = 0; i < lightlist->Size(); i++)
{
secplane_t &lowplane = i == (*lightlist).Size() - 1 ? bottomplane : (*lightlist)[i + 1].plane;
// this must use the exact same calculation method as GLWall::Process etc.
float low1 = lowplane.ZatPoint(vertexes[0]);
float low2 = lowplane.ZatPoint(vertexes[1]);
if (low1 < ztop[0] || low2 < ztop[1])
{
int thisll = (*lightlist)[i].caster != NULL ? hw_ClampLight(*(*lightlist)[i].p_lightlevel) : lightlevel;
FColormap thiscm;
thiscm.FadeColor = Colormap.FadeColor;
thiscm.FogDensity = Colormap.FogDensity;
thiscm.CopyFrom3DLight(&(*lightlist)[i]);
state.SetColor(thisll, rel, false, thiscm, absalpha);
if (type != RENDERWALL_M2SNF) state.SetFog(thisll, rel, false, &thiscm, RenderStyle == STYLE_Add);
state.SetSplitPlanes((*lightlist)[i].plane, lowplane);
RenderWall(di, state, rflags);
}
if (low1 <= zbottom[0] && low2 <= zbottom[1]) break;
}
state.EnableSplit(false);
}
state.SetObjectColor(0xffffffff);
state.SetObjectColor2(0);
state.SetTextureMode(tmode);
state.EnableGlow(false);
}
//==========================================================================
//
//
//
//==========================================================================
void GLWall::RenderTranslucentWall(HWDrawInfo *di, FRenderState &state)
{
state.SetRenderStyle(RenderStyle);
if (gltexture)
{
if (!gltexture->tex->GetTranslucency()) state.AlphaFunc(Alpha_GEqual, gl_mask_threshold);
else state.AlphaFunc(Alpha_GEqual, 0.f);
RenderTexturedWall(di, state, GLWall::RWF_TEXTURED | GLWall::RWF_NOSPLIT);
}
else
{
state.AlphaFunc(Alpha_GEqual, 0.f);
state.SetColor(lightlevel, 0, false, Colormap, fabsf(alpha));
state.SetFog(lightlevel, 0, false, &Colormap, RenderStyle == STYLE_Add);
state.EnableTexture(false);
RenderWall(di, state, GLWall::RWF_NOSPLIT);
state.EnableTexture(true);
}
state.SetRenderStyle(STYLE_Translucent);
}
//==========================================================================
//
//
//
//==========================================================================
void GLWall::DrawWall(HWDrawInfo *di, FRenderState &state, bool translucent)
{
if (screen->BuffersArePersistent())
{
if (level.HasDynamicLights && !di->isFullbrightScene() && gltexture != nullptr)
{
SetupLights(di, lightdata);
}
MakeVertices(di, !!(flags & GLWall::GLWF_TRANSLUCENT));
}
state.SetNormal(glseg.Normal());
if (!translucent)
{
RenderTexturedWall(di, state, GLWall::RWF_TEXTURED);
}
else
{
switch (type)
{
case RENDERWALL_MIRRORSURFACE:
RenderMirrorSurface(di, state);
break;
case RENDERWALL_FOGBOUNDARY:
RenderFogBoundary(di, state);
break;
default:
RenderTranslucentWall(di, state);
break;
}
}
}
//==========================================================================
//