- started reworking the wall drawer.

This commit is contained in:
Christoph Oelckers 2018-10-21 13:11:36 +02:00
parent acad8315d0
commit 7897f26abf
6 changed files with 86 additions and 76 deletions

View file

@ -307,6 +307,15 @@ void FDrawInfo::DrawIndexed(EDrawType dt, FRenderState &state, int index, int co
drawcalls.Unclock(); drawcalls.Unclock();
} }
void FDrawInfo::SetDepthMask(bool on)
{
glDepthMask(on);
}
void FDrawInfo::EnableDrawBufferAttachments(bool on)
{
gl_RenderState.EnableDrawBuffers(on? gl_RenderState.GetPassDrawBufferCount() : 1);
}
//========================================================================== //==========================================================================

View file

@ -54,17 +54,19 @@ struct FDrawInfo : public HWDrawInfo
std::pair<FFlatVertex *, unsigned int> AllocVertices(unsigned int count) override; std::pair<FFlatVertex *, unsigned int> AllocVertices(unsigned int count) override;
int UploadLights(FDynLightData &data) override; int UploadLights(FDynLightData &data) override;
void Draw(EDrawType dt, FRenderState &state, int index, int count, bool apply = true); 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); void DrawIndexed(EDrawType dt, FRenderState &state, int index, int count, bool apply = true) override;
void SetDepthMask(bool on) override;
void EnableDrawBufferAttachments(bool on) override;
void StartScene(); void StartScene();
// Wall drawer // Wall drawer
void RenderWall(GLWall *wall, int textured); void RenderWall(GLWall *wall, FRenderState &state, int textured);
void RenderFogBoundary(GLWall *wall); void RenderFogBoundary(GLWall *wall, FRenderState &state);
void RenderMirrorSurface(GLWall *wall); void RenderMirrorSurface(GLWall *wall, FRenderState &state);
void RenderTranslucentWall(GLWall *wall); void RenderTranslucentWall(GLWall *wall, FRenderState &state);
void RenderTexturedWall(GLWall *wall, int rflags); void RenderTexturedWall(GLWall *wall, FRenderState &state, int rflags);
void DrawWall(GLWall *wall, int pass) override; void DrawWall(GLWall *wall, int pass) override;
// Sprite drawer // Sprite drawer

View file

@ -214,8 +214,6 @@ void FDrawInfo::RenderScene(int recursion)
// //
// RenderTranslucent // RenderTranslucent
// //
// Draws the current draw lists for the non GLSL renderer
//
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void FDrawInfo::RenderTranslucent() void FDrawInfo::RenderTranslucent()

View file

@ -47,12 +47,11 @@ EXTERN_CVAR(Bool, gl_seamless)
// //
//========================================================================== //==========================================================================
void FDrawInfo::RenderWall(GLWall *wall, int textured) void FDrawInfo::RenderWall(GLWall *wall, FRenderState &state, int textured)
{ {
assert(wall->vertcount > 0); assert(wall->vertcount > 0);
gl_RenderState.Apply(); state.SetLightIndex(wall->dynlightindex);
gl_RenderState.ApplyLightIndex(wall->dynlightindex); Draw(DT_TriangleFan, gl_RenderState, wall->vertindex, wall->vertcount);
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, wall->vertindex, wall->vertcount);
vertexcount += wall->vertcount; vertexcount += wall->vertcount;
} }
@ -62,22 +61,20 @@ void FDrawInfo::RenderWall(GLWall *wall, int textured)
// //
//========================================================================== //==========================================================================
void FDrawInfo::RenderFogBoundary(GLWall *wall) void FDrawInfo::RenderFogBoundary(GLWall *wall, FRenderState &state)
{ {
if (gl_fogmode && !isFullbrightScene()) if (gl_fogmode && !isFullbrightScene())
{ {
int rel = wall->rellight + getExtraLight(); int rel = wall->rellight + getExtraLight();
SetFog(wall->lightlevel, rel, &wall->Colormap, false); EnableDrawBufferAttachments(false);
gl_RenderState.EnableDrawBuffers(1); state.SetFog(wall->lightlevel, rel, false, &wall->Colormap, false);
gl_RenderState.SetEffect(EFF_FOGBOUNDARY); state.SetEffect(EFF_FOGBOUNDARY);
gl_RenderState.AlphaFunc(Alpha_GEqual, 0.f); state.AlphaFunc(Alpha_GEqual, 0.f);
glEnable(GL_POLYGON_OFFSET_FILL); state.SetDepthBias(-1, -128);
glPolygonOffset(-1.0f, -128.0f); RenderWall(wall, state, GLWall::RWF_BLANK);
RenderWall(wall, GLWall::RWF_BLANK); state.ClearDepthBias();
glPolygonOffset(0.0f, 0.0f); state.SetEffect(EFF_NONE);
glDisable(GL_POLYGON_OFFSET_FILL); EnableDrawBufferAttachments(true);
gl_RenderState.SetEffect(EFF_NONE);
gl_RenderState.EnableDrawBuffers(gl_RenderState.GetPassDrawBufferCount());
} }
} }
@ -87,34 +84,33 @@ void FDrawInfo::RenderFogBoundary(GLWall *wall)
// //
// //
//========================================================================== //==========================================================================
void FDrawInfo::RenderMirrorSurface(GLWall *wall) void FDrawInfo::RenderMirrorSurface(GLWall *wall, FRenderState &state)
{ {
if (!TexMan.mirrorTexture.isValid()) return; 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. // 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.
gl_RenderState.EnableTextureMatrix(true); state.EnableTextureMatrix(true);
// Use sphere mapping for this // Use sphere mapping for this
gl_RenderState.SetEffect(EFF_SPHEREMAP); state.SetEffect(EFF_SPHEREMAP);
SetColor(wall->lightlevel, 0, wall->Colormap ,0.1f); state.SetColor(wall->lightlevel, 0, isFullbrightScene(), wall->Colormap ,0.1f);
SetFog(wall->lightlevel, 0, &wall->Colormap, true); state.SetFog(wall->lightlevel, 0, isFullbrightScene(), &wall->Colormap, true);
gl_RenderState.BlendFunc(GL_SRC_ALPHA,GL_ONE); state.SetRenderStyle(STYLE_Add);
gl_RenderState.AlphaFunc(Alpha_Greater,0); state.AlphaFunc(Alpha_Greater,0);
glDepthFunc(GL_LEQUAL); glDepthFunc(GL_LEQUAL);
FMaterial * pat=FMaterial::ValidateTexture(TexMan.mirrorTexture, false, false); FMaterial * pat=FMaterial::ValidateTexture(TexMan.mirrorTexture, false, false);
gl_RenderState.ApplyMaterial(pat, CLAMP_NONE, 0, -1); gl_RenderState.ApplyMaterial(pat, CLAMP_NONE, 0, -1);
wall->flags &= ~GLWall::GLWF_GLOW; wall->flags &= ~GLWall::GLWF_GLOW;
RenderWall(wall, GLWall::RWF_BLANK); RenderWall(wall, state, GLWall::RWF_BLANK);
gl_RenderState.EnableTextureMatrix(false); state.EnableTextureMatrix(false);
gl_RenderState.SetEffect(EFF_NONE); state.SetEffect(EFF_NONE);
// Restore the defaults for the translucent pass // Restore the defaults for the translucent pass
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); state.AlphaFunc(Alpha_GEqual, gl_mask_sprite_threshold);
gl_RenderState.AlphaFunc(Alpha_GEqual, gl_mask_sprite_threshold);
glDepthFunc(GL_LESS); glDepthFunc(GL_LESS);
// This is drawn in the translucent pass which is done after the decal pass // This is drawn in the translucent pass which is done after the decal pass
@ -122,11 +118,9 @@ void FDrawInfo::RenderMirrorSurface(GLWall *wall)
// because the depth buffer won't get set by translucent items. // because the depth buffer won't get set by translucent items.
if (wall->seg->sidedef->AttachedDecals) if (wall->seg->sidedef->AttachedDecals)
{ {
glDepthMask(false);
wall->DrawDecalsForMirror(this, gl_RenderState, decals[1]); wall->DrawDecalsForMirror(this, gl_RenderState, decals[1]);
glDepthMask(true);
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
} }
state.SetRenderStyle(STYLE_Translucent);
} }
//========================================================================== //==========================================================================
@ -135,40 +129,40 @@ void FDrawInfo::RenderMirrorSurface(GLWall *wall)
// //
//========================================================================== //==========================================================================
void FDrawInfo::RenderTexturedWall(GLWall *wall, int rflags) void FDrawInfo::RenderTexturedWall(GLWall *wall, FRenderState &state, int rflags)
{ {
int tmode = gl_RenderState.GetTextureMode(); int tmode = state.GetTextureMode();
int rel = wall->rellight + getExtraLight(); int rel = wall->rellight + getExtraLight();
if (wall->flags & GLWall::GLWF_GLOW) if (wall->flags & GLWall::GLWF_GLOW)
{ {
gl_RenderState.EnableGlow(true); state.EnableGlow(true);
gl_RenderState.SetGlowParams(wall->topglowcolor, wall->bottomglowcolor); state.SetGlowParams(wall->topglowcolor, wall->bottomglowcolor);
} }
gl_RenderState.SetGlowPlanes(wall->topplane, wall->bottomplane); state.SetGlowPlanes(wall->topplane, wall->bottomplane);
gl_RenderState.ApplyMaterial(wall->gltexture, wall->flags & 3, 0, -1); state.SetMaterial(wall->gltexture, wall->flags & 3, 0, -1);
if (wall->type == RENDERWALL_M2SNF) if (wall->type == RENDERWALL_M2SNF)
{ {
if (wall->flags & GLWall::GLWF_CLAMPY) if (wall->flags & GLWall::GLWF_CLAMPY)
{ {
if (tmode == TM_NORMAL) gl_RenderState.SetTextureMode(TM_CLAMPY); if (tmode == TM_NORMAL) state.SetTextureMode(TM_CLAMPY);
} }
SetFog(255, 0, nullptr, false); SetFog(255, 0, nullptr, false);
} }
gl_RenderState.SetObjectColor(wall->seg->frontsector->SpecialColors[sector_t::walltop] | 0xff000000); state.SetObjectColor(wall->seg->frontsector->SpecialColors[sector_t::walltop] | 0xff000000);
gl_RenderState.SetObjectColor2(wall->seg->frontsector->SpecialColors[sector_t::wallbottom] | 0xff000000); state.SetObjectColor2(wall->seg->frontsector->SpecialColors[sector_t::wallbottom] | 0xff000000);
float absalpha = fabsf(wall->alpha); float absalpha = fabsf(wall->alpha);
if (wall->lightlist == nullptr) if (wall->lightlist == nullptr)
{ {
if (wall->type != RENDERWALL_M2SNF) SetFog(wall->lightlevel, rel, &wall->Colormap, wall->RenderStyle == STYLE_Add); if (wall->type != RENDERWALL_M2SNF) SetFog(wall->lightlevel, rel, &wall->Colormap, wall->RenderStyle == STYLE_Add);
SetColor(wall->lightlevel, rel, wall->Colormap, absalpha); SetColor(wall->lightlevel, rel, wall->Colormap, absalpha);
RenderWall(wall, rflags); RenderWall(wall, state, rflags);
} }
else else
{ {
gl_RenderState.EnableSplit(true); state.EnableSplit(true);
for (unsigned i = 0; i < wall->lightlist->Size(); i++) for (unsigned i = 0; i < wall->lightlist->Size(); i++)
{ {
@ -184,20 +178,20 @@ void FDrawInfo::RenderTexturedWall(GLWall *wall, int rflags)
thiscm.FadeColor = wall->Colormap.FadeColor; thiscm.FadeColor = wall->Colormap.FadeColor;
thiscm.FogDensity = wall->Colormap.FogDensity; thiscm.FogDensity = wall->Colormap.FogDensity;
thiscm.CopyFrom3DLight(&(*wall->lightlist)[i]); thiscm.CopyFrom3DLight(&(*wall->lightlist)[i]);
SetColor(thisll, rel, thiscm, absalpha); state.SetColor(thisll, rel, false, thiscm, absalpha);
if (wall->type != RENDERWALL_M2SNF) SetFog(thisll, rel, &thiscm, wall->RenderStyle == STYLE_Add); if (wall->type != RENDERWALL_M2SNF) state.SetFog(thisll, rel, false, &thiscm, wall->RenderStyle == STYLE_Add);
gl_RenderState.SetSplitPlanes((*wall->lightlist)[i].plane, lowplane); state.SetSplitPlanes((*wall->lightlist)[i].plane, lowplane);
RenderWall(wall, rflags); RenderWall(wall, state, rflags);
} }
if (low1 <= wall->zbottom[0] && low2 <= wall->zbottom[1]) break; if (low1 <= wall->zbottom[0] && low2 <= wall->zbottom[1]) break;
} }
gl_RenderState.EnableSplit(false); state.EnableSplit(false);
} }
gl_RenderState.SetObjectColor(0xffffffff); state.SetObjectColor(0xffffffff);
gl_RenderState.SetObjectColor2(0); state.SetObjectColor2(0);
gl_RenderState.SetTextureMode(tmode); state.SetTextureMode(tmode);
gl_RenderState.EnableGlow(false); state.EnableGlow(false);
} }
//========================================================================== //==========================================================================
@ -206,25 +200,25 @@ void FDrawInfo::RenderTexturedWall(GLWall *wall, int rflags)
// //
//========================================================================== //==========================================================================
void FDrawInfo::RenderTranslucentWall(GLWall *wall) void FDrawInfo::RenderTranslucentWall(GLWall *wall, FRenderState &state)
{ {
state.SetRenderStyle(wall->RenderStyle);
if (wall->gltexture) if (wall->gltexture)
{ {
if (!wall->gltexture->tex->GetTranslucency()) gl_RenderState.AlphaFunc(Alpha_GEqual, gl_mask_threshold); if (!wall->gltexture->tex->GetTranslucency()) state.AlphaFunc(Alpha_GEqual, gl_mask_threshold);
else gl_RenderState.AlphaFunc(Alpha_GEqual, 0.f); else state.AlphaFunc(Alpha_GEqual, 0.f);
if (wall->RenderStyle == STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA,GL_ONE); RenderTexturedWall(wall, state, GLWall::RWF_TEXTURED | GLWall::RWF_NOSPLIT);
RenderTexturedWall(wall, GLWall::RWF_TEXTURED | GLWall::RWF_NOSPLIT);
if (wall->RenderStyle == STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
} }
else else
{ {
gl_RenderState.AlphaFunc(Alpha_GEqual, 0.f); state.AlphaFunc(Alpha_GEqual, 0.f);
SetColor(wall->lightlevel, 0, wall->Colormap, fabsf(wall->alpha)); state.SetColor(wall->lightlevel, 0, false, wall->Colormap, fabsf(wall->alpha));
SetFog(wall->lightlevel, 0, &wall->Colormap, wall->RenderStyle == STYLE_Add); state.SetFog(wall->lightlevel, 0, false, &wall->Colormap, wall->RenderStyle == STYLE_Add);
gl_RenderState.EnableTexture(false); state.EnableTexture(false);
RenderWall(wall, GLWall::RWF_NOSPLIT); RenderWall(wall, state, GLWall::RWF_NOSPLIT);
gl_RenderState.EnableTexture(true); state.EnableTexture(true);
} }
state.SetRenderStyle(STYLE_Translucent);
} }
//========================================================================== //==========================================================================
@ -234,6 +228,7 @@ void FDrawInfo::RenderTranslucentWall(GLWall *wall)
//========================================================================== //==========================================================================
void FDrawInfo::DrawWall(GLWall *wall, int pass) void FDrawInfo::DrawWall(GLWall *wall, int pass)
{ {
FRenderState &state = gl_RenderState;
if (screen->BuffersArePersistent()) if (screen->BuffersArePersistent())
{ {
if (level.HasDynamicLights && !isFullbrightScene() && wall->gltexture != nullptr) if (level.HasDynamicLights && !isFullbrightScene() && wall->gltexture != nullptr)
@ -247,7 +242,7 @@ void FDrawInfo::DrawWall(GLWall *wall, int pass)
switch (pass) switch (pass)
{ {
case GLPASS_ALL: case GLPASS_ALL:
RenderTexturedWall(wall, GLWall::RWF_TEXTURED); RenderTexturedWall(wall, state, GLWall::RWF_TEXTURED);
break; break;
case GLPASS_TRANSLUCENT: case GLPASS_TRANSLUCENT:
@ -255,15 +250,15 @@ void FDrawInfo::DrawWall(GLWall *wall, int pass)
switch (wall->type) switch (wall->type)
{ {
case RENDERWALL_MIRRORSURFACE: case RENDERWALL_MIRRORSURFACE:
RenderMirrorSurface(wall); RenderMirrorSurface(wall, state);
break; break;
case RENDERWALL_FOGBOUNDARY: case RENDERWALL_FOGBOUNDARY:
RenderFogBoundary(wall); RenderFogBoundary(wall, state);
break; break;
default: default:
RenderTranslucentWall(wall); RenderTranslucentWall(wall, state);
break; break;
} }
break; break;

View file

@ -163,6 +163,7 @@ void HWDrawInfo::DrawDecals(FRenderState &state, TArray<GLDecal *> &decals)
void GLWall::DrawDecalsForMirror(HWDrawInfo *di, FRenderState &state, TArray<GLDecal *> &decals) void GLWall::DrawDecalsForMirror(HWDrawInfo *di, FRenderState &state, TArray<GLDecal *> &decals)
{ {
di->SetDepthMask(false);
state.SetDepthBias(-1, -128); state.SetDepthBias(-1, -128);
state.SetFog(lightlevel, rellight + getExtraLight(), di->isFullbrightScene(), &Colormap, false); state.SetFog(lightlevel, rellight + getExtraLight(), di->isFullbrightScene(), &Colormap, false);
for (auto gldecal : decals) for (auto gldecal : decals)
@ -174,6 +175,7 @@ void GLWall::DrawDecalsForMirror(HWDrawInfo *di, FRenderState &state, TArray<GLD
} }
state.ClearDepthBias(); state.ClearDepthBias();
state.SetTextureMode(TM_NORMAL); state.SetTextureMode(TM_NORMAL);
di->SetDepthMask(true);
} }
//========================================================================== //==========================================================================

View file

@ -309,5 +309,9 @@ public:
virtual void Draw(EDrawType dt, FRenderState &state, int index, int count, bool apply = true) = 0; virtual void Draw(EDrawType dt, FRenderState &state, int index, int count, bool apply = true) = 0;
virtual void DrawIndexed(EDrawType dt, FRenderState &state, int index, int count, bool apply = true) = 0; virtual void DrawIndexed(EDrawType dt, FRenderState &state, int index, int count, bool apply = true) = 0;
// Immediate render state change commands. These only change infrequently and should not clutter the render state.
virtual void SetDepthMask(bool on) = 0;
virtual void EnableDrawBufferAttachments(bool on) = 0;
}; };