- moved the flat drawer to hwrenderer.

This commit is contained in:
Christoph Oelckers 2018-10-21 00:35:39 +02:00
parent e8f48e7535
commit d45f6b9bea
9 changed files with 181 additions and 217 deletions

View file

@ -90,13 +90,13 @@ void FDrawInfo::DoDrawSorted(HWDrawList *dl, SortNode * head)
DoDrawSorted(dl, head->left); DoDrawSorted(dl, head->left);
gl_RenderState.SetClipSplit(clipsplit); 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) if (head->equal)
{ {
SortNode * ehead=head->equal; SortNode * ehead=head->equal;
while (ehead) while (ehead)
{ {
dl->DoDraw(this, GLPASS_TRANSLUCENT, ehead->itemindex, true); dl->DoDraw(this, gl_RenderState, true, GLPASS_TRANSLUCENT, ehead->itemindex, true);
ehead=ehead->equal; ehead=ehead->equal;
} }
} }

View file

@ -76,11 +76,6 @@ struct FDrawInfo : public HWDrawInfo
void RenderTexturedWall(GLWall *wall, int rflags); void RenderTexturedWall(GLWall *wall, int rflags);
void DrawWall(GLWall *wall, int pass) override; 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 // Sprite drawer
void DrawSprite(GLSprite *sprite, int pass); void DrawSprite(GLSprite *sprite, int pass);
void DrawPSprite(HUDSprite *huds); void DrawPSprite(HUDSprite *huds);

View file

@ -47,202 +47,6 @@
#include "gl/scene/gl_drawinfo.h" #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 // FDrawInfo::AddFlat

View file

@ -174,7 +174,7 @@ void FDrawInfo::RenderScene(int recursion)
gl_RenderState.EnableTexture(gl_texture); gl_RenderState.EnableTexture(gl_texture);
gl_RenderState.EnableBrightmap(true); gl_RenderState.EnableBrightmap(true);
drawlists[GLDL_PLAINWALLS].DrawWalls(this, pass); 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 // 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); gl_RenderState.AlphaFunc(Alpha_GEqual, gl_mask_threshold);
drawlists[GLDL_MASKEDWALLS].DrawWalls(this, pass); 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. // 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) if (drawlists[GLDL_MASKEDWALLSOFS].Size() > 0)
@ -197,7 +197,7 @@ void FDrawInfo::RenderScene(int recursion)
glPolygonOffset(0, 0); 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); 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.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
gl_RenderState.EnableBrightmap(true); gl_RenderState.EnableBrightmap(true);
drawlists[GLDL_TRANSLUCENTBORDER].Draw(this, GLPASS_TRANSLUCENT); drawlists[GLDL_TRANSLUCENTBORDER].Draw(this, gl_RenderState, true, GLPASS_TRANSLUCENT);
glDepthMask(false); glDepthMask(false);
DrawSorted(GLDL_TRANSLUCENT); DrawSorted(GLDL_TRANSLUCENT);
gl_RenderState.EnableBrightmap(false); gl_RenderState.EnableBrightmap(false);

View file

@ -285,7 +285,6 @@ public:
angle_t FrustumAngle(); angle_t FrustumAngle();
virtual void DrawWall(GLWall *wall, int pass) = 0; 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; virtual void DrawSprite(GLSprite *sprite, int pass) = 0;
void ProcessLowerMinisegs(TArray<seg_t *> &lowersegs); void ProcessLowerMinisegs(TArray<seg_t *> &lowersegs);

View file

@ -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) 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]; GLFlat * f= flats[drawitems[i].index];
RenderFlat.Clock(); RenderFlat.Clock();
di->DrawFlat(f, pass, trans); f->DrawFlat(di, state, translucent);
RenderFlat.Unclock(); RenderFlat.Unclock();
} }
break; 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++) 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(); RenderFlat.Clock();
for (unsigned i = 0; i<drawitems.Size(); i++) for (unsigned i = 0; i<drawitems.Size(); i++)
{ {
di->DrawFlat(flats[drawitems[i].index], pass, false); flats[drawitems[i].index]->DrawFlat(di, state, translucent);
} }
RenderFlat.Unclock(); RenderFlat.Unclock();
} }

View file

@ -103,10 +103,10 @@ public:
SortNode * DoSort(HWDrawInfo *di, SortNode * head); SortNode * DoSort(HWDrawInfo *di, SortNode * head);
void Sort(HWDrawInfo *di); void Sort(HWDrawInfo *di);
void DoDraw(HWDrawInfo *di, int pass, int index, bool trans); void DoDraw(HWDrawInfo *di, FRenderState &state, bool translucent, int pass, int i, bool trans);
void Draw(HWDrawInfo *di, int pass, bool trans = false); void Draw(HWDrawInfo *di, FRenderState &state, bool translucent, int pass, bool trans = false);
void DrawWalls(HWDrawInfo *di, int pass); void DrawWalls(HWDrawInfo *di, int pass);
void DrawFlats(HWDrawInfo *di, int pass); void DrawFlats(HWDrawInfo *di, FRenderState &state, bool translucent);
HWDrawList * next; HWDrawList * next;
} ; } ;

View file

@ -25,6 +25,7 @@ struct FDynLightData;
class VSMatrix; class VSMatrix;
struct FSpriteModelFrame; struct FSpriteModelFrame;
struct particle_t; struct particle_t;
class FRenderState;
enum area_t : int; enum area_t : int;
enum HWRenderStyle enum HWRenderStyle
@ -321,6 +322,9 @@ public:
void SetFrom3DFloor(F3DFloor *rover, bool top, bool underside); void SetFrom3DFloor(F3DFloor *rover, bool top, bool underside);
void ProcessSector(HWDrawInfo *di, sector_t * frontsector); void ProcessSector(HWDrawInfo *di, sector_t * frontsector);
void DrawSubsectors(HWDrawInfo *di, FRenderState &state);
void DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent);
GLFlat() {} GLFlat() {}
GLFlat(const GLFlat &other) GLFlat(const GLFlat &other)

View file

@ -43,6 +43,7 @@
#include "hwrenderer/scene/hw_drawinfo.h" #include "hwrenderer/scene/hw_drawinfo.h"
#include "hwrenderer/data/flatvertices.h" #include "hwrenderer/data/flatvertices.h"
#include "hw_drawstructs.h" #include "hw_drawstructs.h"
#include "hw_renderstate.h"
#ifdef _DEBUG #ifdef _DEBUG
CVAR(Int, gl_breaksec, -1, 0) CVAR(Int, gl_breaksec, -1, 0)
@ -172,6 +173,167 @@ void GLFlat::SetupLights(HWDrawInfo *di, FLightNode * node, FDynLightData &light
dynlightindex = di->UploadLights(lightdata); 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 // GLFlat::PutFlat