From d45f6b9bea4af0ff4304feabdf94117a40460cfe Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 21 Oct 2018 00:35:39 +0200 Subject: [PATCH] - moved the flat drawer to hwrenderer. --- src/gl/scene/gl_drawinfo.cpp | 4 +- src/gl/scene/gl_drawinfo.h | 5 - src/gl/scene/gl_flats.cpp | 196 -------------------------- src/gl/scene/gl_scene.cpp | 8 +- src/hwrenderer/scene/hw_drawinfo.h | 1 - src/hwrenderer/scene/hw_drawlist.cpp | 12 +- src/hwrenderer/scene/hw_drawlist.h | 6 +- src/hwrenderer/scene/hw_drawstructs.h | 4 + src/hwrenderer/scene/hw_flats.cpp | 162 +++++++++++++++++++++ 9 files changed, 181 insertions(+), 217 deletions(-) diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index d7808635a..8f56f4a89 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -90,13 +90,13 @@ void FDrawInfo::DoDrawSorted(HWDrawList *dl, SortNode * head) DoDrawSorted(dl, head->left); gl_RenderState.SetClipSplit(clipsplit); } - dl->DoDraw(this, GLPASS_TRANSLUCENT, head->itemindex, true); + dl->DoDraw(this, gl_RenderState, true, GLPASS_TRANSLUCENT, head->itemindex, true); if (head->equal) { SortNode * ehead=head->equal; while (ehead) { - dl->DoDraw(this, GLPASS_TRANSLUCENT, ehead->itemindex, true); + dl->DoDraw(this, gl_RenderState, true, GLPASS_TRANSLUCENT, ehead->itemindex, true); ehead=ehead->equal; } } diff --git a/src/gl/scene/gl_drawinfo.h b/src/gl/scene/gl_drawinfo.h index 2c1d297c2..54ed46d59 100644 --- a/src/gl/scene/gl_drawinfo.h +++ b/src/gl/scene/gl_drawinfo.h @@ -76,11 +76,6 @@ struct FDrawInfo : public HWDrawInfo void RenderTexturedWall(GLWall *wall, int rflags); void DrawWall(GLWall *wall, int pass) override; - // Flat drawer - void DrawFlat(GLFlat *flat, int pass, bool trans) override; // trans only has meaning for GLPASS_LIGHTSONLY - void DrawSkyboxSector(GLFlat *flat, int pass); - void DrawSubsectors(GLFlat *flat, int pass, bool istrans); - // Sprite drawer void DrawSprite(GLSprite *sprite, int pass); void DrawPSprite(HUDSprite *huds); diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 397c280f2..464d19ac3 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -47,202 +47,6 @@ #include "gl/scene/gl_drawinfo.h" -//========================================================================== -// -// -// -//========================================================================== - -void FDrawInfo::DrawSubsectors(GLFlat *flat, int pass, bool istrans) -{ - int dli = flat->dynlightindex; - auto vcount = flat->sector->ibocount; - - gl_RenderState.Apply(); - auto iboindex = flat->iboindex; - - - if (screen->BuffersArePersistent()) - { - flat->SetupLights(this, flat->sector->lighthead, lightdata, flat->sector->PortalGroup); - } - gl_RenderState.ApplyLightIndex(flat->dynlightindex); - if (vcount > 0 && !ClipLineShouldBeActive()) - { - DrawIndexed(DT_Triangles, gl_RenderState, iboindex, vcount); - flatvertices += vcount; - flatprimitives++; - } - else - { - int index = iboindex; - for (int i = 0; i < flat->sector->subsectorcount; i++) - { - subsector_t * sub = flat->sector->subsectors[i]; - if (sub->numlines <= 2) continue; - - if (ss_renderflags[sub->Index()] & flat->renderflags || istrans) - { - DrawIndexed(DT_Triangles, gl_RenderState, index, (sub->numlines - 2) * 3, false); - drawcalls.Unclock(); - flatvertices += sub->numlines; - flatprimitives++; - } - index += (sub->numlines - 2) * 3; - } - } - - if (!(flat->renderflags&SSRF_RENDER3DPLANES)) - { - // Draw the subsectors assigned to it due to missing textures - gl_subsectorrendernode * node = (flat->renderflags&SSRF_RENDERFLOOR)? - GetOtherFloorPlanes(flat->sector->sectornum) : - GetOtherCeilingPlanes(flat->sector->sectornum); - - while (node) - { - gl_RenderState.ApplyLightIndex(node->lightindex); - auto num = node->sub->numlines; - flatvertices += num; - flatprimitives++; - Draw(DT_TriangleFan, gl_RenderState, node->vertexindex, num); - node = node->next; - } - // Flood gaps with the back side's ceiling/floor texture - // This requires a stencil because the projected plane interferes with - // the depth buffer - gl_floodrendernode * fnode = (flat->renderflags&SSRF_RENDERFLOOR) ? - GetFloodFloorSegs(flat->sector->sectornum) : - GetFloodCeilingSegs(flat->sector->sectornum); - - gl_RenderState.ApplyLightIndex(flat->dynlightindex); - while (fnode) - { - flatvertices += 12; - flatprimitives+=3; - - // Push bleeding floor/ceiling textures back a little in the z-buffer - // so they don't interfere with overlapping mid textures. - gl_RenderState.SetDepthBias(1, 128); - SetupFloodStencil(fnode->vertexindex); - Draw(DT_TriangleFan, gl_RenderState, fnode->vertexindex + 4, 4); - ClearFloodStencil(fnode->vertexindex); - gl_RenderState.SetDepthBias(0, 0); - - fnode = fnode->next; - } - - } -} - -//========================================================================== -// -// -//========================================================================== - -void FDrawInfo::SetupFloodStencil(int vindex) -{ - int recursion = GLRenderer->mPortalState.GetRecursion(); - - // Create stencil - gl_RenderState.SetEffect(EFF_STENCIL); - gl_RenderState.EnableTexture(false); - gl_RenderState.Apply(); - - gl_RenderState.SetStencil(0, SOP_Increment, SF_ColorMaskOff); - - Draw(DT_TriangleFan, gl_RenderState, vindex, 4); - - gl_RenderState.SetStencil(1, SOP_Keep, SF_DepthMaskOff | SF_DepthTestOff); - - gl_RenderState.EnableTexture(true); - gl_RenderState.SetEffect(EFF_NONE); - gl_RenderState.Apply(); -} - -void FDrawInfo::ClearFloodStencil(int vindex) -{ - int recursion = GLRenderer->mPortalState.GetRecursion(); - - gl_RenderState.SetEffect(EFF_STENCIL); - gl_RenderState.EnableTexture(false); - gl_RenderState.Apply(); - - gl_RenderState.SetStencil(1, SOP_Decrement, SF_ColorMaskOff | SF_DepthMaskOff | SF_DepthTestOff); - - Draw(DT_TriangleFan, gl_RenderState, vindex, 4); - - // restore old stencil op. - gl_RenderState.SetStencil(0, SOP_Keep, SF_AllOn); - gl_RenderState.EnableTexture(true); - gl_RenderState.SetEffect(EFF_NONE); -} - -//========================================================================== -// -// -// -//========================================================================== -void FDrawInfo::DrawFlat(GLFlat *flat, int pass, bool trans) // trans only has meaning for GLPASS_LIGHTSONLY -{ - int rel = getExtraLight(); - - auto &plane = flat->plane; - gl_RenderState.SetNormal(plane.plane.Normal().X, plane.plane.Normal().Z, plane.plane.Normal().Y); - - switch (pass) - { - case GLPASS_ALL: // Single-pass rendering - SetColor(flat->lightlevel, rel, flat->Colormap,1.0f); - SetFog(flat->lightlevel, rel, &flat->Colormap, false); - if (!flat->gltexture->tex->isFullbright()) - gl_RenderState.SetObjectColor(flat->FlatColor | 0xff000000); - if (flat->sector->special != GLSector_Skybox) - { - gl_RenderState.ApplyMaterial(flat->gltexture, CLAMP_NONE, 0, -1); - gl_RenderState.SetPlaneTextureRotation(&plane, flat->gltexture); - DrawSubsectors(flat, pass, false); - gl_RenderState.EnableTextureMatrix(false); - } - else - { - gl_RenderState.ApplyMaterial(flat->gltexture, CLAMP_XY, 0, -1); - gl_RenderState.SetLightIndex(flat->dynlightindex); - Draw(DT_TriangleFan, gl_RenderState, flat->iboindex, 4); - flatvertices += 4; - flatprimitives++; - } - gl_RenderState.SetObjectColor(0xffffffff); - break; - - case GLPASS_TRANSLUCENT: - gl_RenderState.SetRenderStyle(flat->renderstyle); - SetColor(flat->lightlevel, rel, flat->Colormap, flat->alpha); - SetFog(flat->lightlevel, rel, &flat->Colormap, false); - if (!flat->gltexture || !flat->gltexture->tex->isFullbright()) - gl_RenderState.SetObjectColor(flat->FlatColor | 0xff000000); - if (!flat->gltexture) - { - gl_RenderState.AlphaFunc(Alpha_GEqual, 0.f); - gl_RenderState.EnableTexture(false); - DrawSubsectors(flat, pass, true); - gl_RenderState.EnableTexture(true); - } - else - { - if (!flat->gltexture->tex->GetTranslucency()) gl_RenderState.AlphaFunc(Alpha_GEqual, gl_mask_threshold); - else gl_RenderState.AlphaFunc(Alpha_GEqual, 0.f); - gl_RenderState.ApplyMaterial(flat->gltexture, CLAMP_NONE, 0, -1); - gl_RenderState.SetPlaneTextureRotation(&plane, flat->gltexture); - DrawSubsectors(flat, pass, true); - gl_RenderState.EnableTextureMatrix(false); - } - gl_RenderState.SetRenderStyle(DefaultRenderStyle()); - gl_RenderState.SetObjectColor(0xffffffff); - break; - } -} - //========================================================================== // // FDrawInfo::AddFlat diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index a20f93696..60ba54e00 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -174,7 +174,7 @@ void FDrawInfo::RenderScene(int recursion) gl_RenderState.EnableTexture(gl_texture); gl_RenderState.EnableBrightmap(true); drawlists[GLDL_PLAINWALLS].DrawWalls(this, pass); - drawlists[GLDL_PLAINFLATS].DrawFlats(this, pass); + drawlists[GLDL_PLAINFLATS].DrawFlats(this, gl_RenderState, false); // Part 2: masked geometry. This is set up so that only pixels with alpha>gl_mask_threshold will show @@ -185,7 +185,7 @@ void FDrawInfo::RenderScene(int recursion) } gl_RenderState.AlphaFunc(Alpha_GEqual, gl_mask_threshold); drawlists[GLDL_MASKEDWALLS].DrawWalls(this, pass); - drawlists[GLDL_MASKEDFLATS].DrawFlats(this, pass); + 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) @@ -197,7 +197,7 @@ void FDrawInfo::RenderScene(int recursion) glPolygonOffset(0, 0); } - drawlists[GLDL_MODELS].Draw(this, pass); + drawlists[GLDL_MODELS].Draw(this, gl_RenderState, false, pass); gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -232,7 +232,7 @@ void FDrawInfo::RenderTranslucent() gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_RenderState.EnableBrightmap(true); - drawlists[GLDL_TRANSLUCENTBORDER].Draw(this, GLPASS_TRANSLUCENT); + drawlists[GLDL_TRANSLUCENTBORDER].Draw(this, gl_RenderState, true, GLPASS_TRANSLUCENT); glDepthMask(false); DrawSorted(GLDL_TRANSLUCENT); gl_RenderState.EnableBrightmap(false); diff --git a/src/hwrenderer/scene/hw_drawinfo.h b/src/hwrenderer/scene/hw_drawinfo.h index 471bb5bbe..ec2c618af 100644 --- a/src/hwrenderer/scene/hw_drawinfo.h +++ b/src/hwrenderer/scene/hw_drawinfo.h @@ -285,7 +285,6 @@ public: angle_t FrustumAngle(); virtual void DrawWall(GLWall *wall, int pass) = 0; - virtual void DrawFlat(GLFlat *flat, int pass, bool trans) = 0; virtual void DrawSprite(GLSprite *sprite, int pass) = 0; void ProcessLowerMinisegs(TArray &lowersegs); diff --git a/src/hwrenderer/scene/hw_drawlist.cpp b/src/hwrenderer/scene/hw_drawlist.cpp index c1677646b..aab639bdb 100644 --- a/src/hwrenderer/scene/hw_drawlist.cpp +++ b/src/hwrenderer/scene/hw_drawlist.cpp @@ -771,7 +771,7 @@ GLSprite *HWDrawList::NewSprite() // // //========================================================================== -void HWDrawList::DoDraw(HWDrawInfo *di, int pass, int i, bool trans) +void HWDrawList::DoDraw(HWDrawInfo *di, FRenderState &state, bool translucent, int pass, int i, bool trans) { switch(drawitems[i].rendertype) { @@ -779,7 +779,7 @@ void HWDrawList::DoDraw(HWDrawInfo *di, int pass, int i, bool trans) { GLFlat * f= flats[drawitems[i].index]; RenderFlat.Clock(); - di->DrawFlat(f, pass, trans); + f->DrawFlat(di, state, translucent); RenderFlat.Unclock(); } break; @@ -809,11 +809,11 @@ void HWDrawList::DoDraw(HWDrawInfo *di, int pass, int i, bool trans) // // //========================================================================== -void HWDrawList::Draw(HWDrawInfo *di, int pass, bool trans) +void HWDrawList::Draw(HWDrawInfo *di, FRenderState &state, bool translucent, int pass, bool trans) { for (unsigned i = 0; i < drawitems.Size(); i++) { - DoDraw(di, pass, i, trans); + DoDraw(di, state, translucent, pass, i, trans); } } @@ -837,12 +837,12 @@ void HWDrawList::DrawWalls(HWDrawInfo *di, int pass) // // //========================================================================== -void HWDrawList::DrawFlats(HWDrawInfo *di, int pass) +void HWDrawList::DrawFlats(HWDrawInfo *di, FRenderState &state, bool translucent) { RenderFlat.Clock(); for (unsigned i = 0; iDrawFlat(flats[drawitems[i].index], pass, false); + flats[drawitems[i].index]->DrawFlat(di, state, translucent); } RenderFlat.Unclock(); } diff --git a/src/hwrenderer/scene/hw_drawlist.h b/src/hwrenderer/scene/hw_drawlist.h index 22bf1cb31..bfab10371 100644 --- a/src/hwrenderer/scene/hw_drawlist.h +++ b/src/hwrenderer/scene/hw_drawlist.h @@ -103,10 +103,10 @@ public: SortNode * DoSort(HWDrawInfo *di, SortNode * head); void Sort(HWDrawInfo *di); - void DoDraw(HWDrawInfo *di, int pass, int index, bool trans); - void Draw(HWDrawInfo *di, int pass, bool trans = false); + 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 DrawFlats(HWDrawInfo *di, int pass); + void DrawFlats(HWDrawInfo *di, FRenderState &state, bool translucent); HWDrawList * next; } ; diff --git a/src/hwrenderer/scene/hw_drawstructs.h b/src/hwrenderer/scene/hw_drawstructs.h index ff175efe1..94310ac69 100644 --- a/src/hwrenderer/scene/hw_drawstructs.h +++ b/src/hwrenderer/scene/hw_drawstructs.h @@ -25,6 +25,7 @@ struct FDynLightData; class VSMatrix; struct FSpriteModelFrame; struct particle_t; +class FRenderState; enum area_t : int; enum HWRenderStyle @@ -321,6 +322,9 @@ public: void SetFrom3DFloor(F3DFloor *rover, bool top, bool underside); void ProcessSector(HWDrawInfo *di, sector_t * frontsector); + void DrawSubsectors(HWDrawInfo *di, FRenderState &state); + void DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent); + GLFlat() {} GLFlat(const GLFlat &other) diff --git a/src/hwrenderer/scene/hw_flats.cpp b/src/hwrenderer/scene/hw_flats.cpp index e1580caca..7527fc4b9 100644 --- a/src/hwrenderer/scene/hw_flats.cpp +++ b/src/hwrenderer/scene/hw_flats.cpp @@ -43,6 +43,7 @@ #include "hwrenderer/scene/hw_drawinfo.h" #include "hwrenderer/data/flatvertices.h" #include "hw_drawstructs.h" +#include "hw_renderstate.h" #ifdef _DEBUG CVAR(Int, gl_breaksec, -1, 0) @@ -172,6 +173,167 @@ void GLFlat::SetupLights(HWDrawInfo *di, FLightNode * node, FDynLightData &light dynlightindex = di->UploadLights(lightdata); } +//========================================================================== +// +// +// +//========================================================================== + +void GLFlat::DrawSubsectors(HWDrawInfo *di, FRenderState &state) +{ + auto vcount = sector->ibocount; + + if (screen->BuffersArePersistent()) + { + SetupLights(di, sector->lighthead, lightdata, sector->PortalGroup); + } + state.SetLightIndex(dynlightindex); + if (vcount > 0 && !di->ClipLineShouldBeActive()) + { + di->DrawIndexed(DT_Triangles, state, iboindex, vcount); + flatvertices += vcount; + flatprimitives++; + } + else + { + int index = iboindex; + for (int i = 0; i < sector->subsectorcount; i++) + { + subsector_t * sub = sector->subsectors[i]; + if (sub->numlines <= 2) continue; + + if (di->ss_renderflags[sub->Index()] & renderflags) + { + di->DrawIndexed(DT_Triangles, state, index, (sub->numlines - 2) * 3, false); + flatvertices += sub->numlines; + flatprimitives++; + } + index += (sub->numlines - 2) * 3; + } + } + + if (!(renderflags&SSRF_RENDER3DPLANES)) + { + // Draw the subsectors assigned to it due to missing textures + gl_subsectorrendernode * node = (renderflags&SSRF_RENDERFLOOR) ? + di->GetOtherFloorPlanes(sector->sectornum) : + di->GetOtherCeilingPlanes(sector->sectornum); + + while (node) + { + state.SetLightIndex(node->lightindex); + auto num = node->sub->numlines; + flatvertices += num; + flatprimitives++; + di->Draw(DT_TriangleFan, state, node->vertexindex, num); + node = node->next; + } + // Flood gaps with the back side's ceiling/floor texture + // This requires a stencil because the projected plane interferes with + // the depth buffer + gl_floodrendernode * fnode = (renderflags&SSRF_RENDERFLOOR) ? + di->GetFloodFloorSegs(sector->sectornum) : + di->GetFloodCeilingSegs(sector->sectornum); + + state.SetLightIndex(dynlightindex); + while (fnode) + { + flatvertices += 12; + flatprimitives += 3; + + // Push bleeding floor/ceiling textures back a little in the z-buffer + // so they don't interfere with overlapping mid textures. + state.SetDepthBias(1, 128); + + // Create stencil + state.SetEffect(EFF_STENCIL); + state.EnableTexture(false); + state.SetStencil(0, SOP_Increment, SF_ColorMaskOff); + di->Draw(DT_TriangleFan, state, fnode->vertexindex, 4); + + // Draw projected plane into stencil + state.SetStencil(1, SOP_Keep, SF_DepthMaskOff | SF_DepthTestOff); + state.EnableTexture(true); + state.SetEffect(EFF_NONE); + di->Draw(DT_TriangleFan, state, fnode->vertexindex + 4, 4); + + // clear stencil + state.SetEffect(EFF_STENCIL); + state.EnableTexture(false); + state.SetStencil(1, SOP_Decrement, SF_ColorMaskOff | SF_DepthMaskOff | SF_DepthTestOff); + di->Draw(DT_TriangleFan, state, fnode->vertexindex, 4); + + // restore old stencil op. + state.SetStencil(0, SOP_Keep, SF_AllOn); + state.EnableTexture(true); + state.SetEffect(EFF_NONE); + state.SetDepthBias(0, 0); + + fnode = fnode->next; + } + + } +} + +//========================================================================== +// +// +// +//========================================================================== +void GLFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent) +{ + int rel = getExtraLight(); + + state.SetNormal(plane.plane.Normal().X, plane.plane.Normal().Z, plane.plane.Normal().Y); + + state.SetColor(lightlevel, rel, di->isFullbrightScene(), Colormap, alpha); + state.SetFog(lightlevel, rel, di->isFullbrightScene(), &Colormap, false); + if (!gltexture || !gltexture->tex->isFullbright()) + state.SetObjectColor(FlatColor | 0xff000000); + + if (!translucent) + { + if (sector->special != GLSector_Skybox) + { + state.SetMaterial(gltexture, CLAMP_NONE, 0, -1); + state.SetPlaneTextureRotation(&plane, gltexture); + DrawSubsectors(di, state); + state.EnableTextureMatrix(false); + } + else + { + state.SetMaterial(gltexture, CLAMP_XY, 0, -1); + state.SetLightIndex(dynlightindex); + di->Draw(DT_TriangleFan, state, iboindex, 4); + flatvertices += 4; + flatprimitives++; + } + state.SetObjectColor(0xffffffff); + } + else + { + state.SetRenderStyle(renderstyle); + if (!gltexture) + { + state.AlphaFunc(Alpha_GEqual, 0.f); + state.EnableTexture(false); + DrawSubsectors(di, state); + state.EnableTexture(true); + } + else + { + if (!gltexture->tex->GetTranslucency()) state.AlphaFunc(Alpha_GEqual, gl_mask_threshold); + else state.AlphaFunc(Alpha_GEqual, 0.f); + state.SetMaterial(gltexture, CLAMP_NONE, 0, -1); + state.SetPlaneTextureRotation(&plane, gltexture); + DrawSubsectors(di, state); + state.EnableTextureMatrix(false); + } + state.SetRenderStyle(DefaultRenderStyle()); + state.SetObjectColor(0xffffffff); + } +} + //========================================================================== // // GLFlat::PutFlat