mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-29 07:22:07 +00:00
- finished decal render refactoring.
Decals will now be processed into a list in the processing pass, allowing to use the vertex buffer even on GL3 hardware and to offload this part of the work to a multithreaded worker task.
This commit is contained in:
parent
1ae2f06161
commit
0d7c2527f2
9 changed files with 85 additions and 76 deletions
|
@ -40,28 +40,6 @@
|
|||
#include "gl/scene/gl_scenedrawer.h"
|
||||
#include "gl/renderer/gl_quaddrawer.h"
|
||||
|
||||
struct DecalVertex
|
||||
{
|
||||
float x,y,z;
|
||||
float u,v;
|
||||
};
|
||||
|
||||
struct GLDecal
|
||||
{
|
||||
unsigned int vertindex;
|
||||
FMaterial *gltexture;
|
||||
GLWall *wall;
|
||||
DBaseDecal *decal;
|
||||
DecalVertex dv[4];
|
||||
float zcenter;
|
||||
|
||||
int light;
|
||||
int rel;
|
||||
float a;
|
||||
FColormap colormap;
|
||||
|
||||
};
|
||||
|
||||
void GLWall::ProcessDecal(HWDrawInfo *di, DBaseDecal *decal)
|
||||
{
|
||||
line_t * line = seg->linedef;
|
||||
|
@ -70,11 +48,11 @@ void GLWall::ProcessDecal(HWDrawInfo *di, DBaseDecal *decal)
|
|||
float zpos;
|
||||
bool flipx, flipy;
|
||||
FTextureID decalTile;
|
||||
GLDecal gldecal;
|
||||
|
||||
|
||||
if (decal->RenderFlags & RF_INVISIBLE) return;
|
||||
if (type == RENDERWALL_FFBLOCK && gltexture->isMasked()) return; // No decals on 3D floors with transparent textures.
|
||||
if (seg == nullptr) return;
|
||||
|
||||
|
||||
decalTile = decal->PicNum;
|
||||
|
@ -138,8 +116,8 @@ void GLWall::ProcessDecal(HWDrawInfo *di, DBaseDecal *decal)
|
|||
zpos = decal->Z + frontsector->GetPlaneTexZ(sector_t::ceiling);
|
||||
}
|
||||
}
|
||||
|
||||
memset(&gldecal, 0, sizeof(gldecal));
|
||||
|
||||
GLDecal &gldecal = *di->AddDecal(type == RENDERWALL_MIRRORSURFACE);
|
||||
gldecal.gltexture = FMaterial::ValidateTexture(texture, true);
|
||||
gldecal.wall = this;
|
||||
gldecal.decal = decal;
|
||||
|
@ -286,7 +264,6 @@ void GLWall::ProcessDecal(HWDrawInfo *di, DBaseDecal *decal)
|
|||
{
|
||||
verts.first[i].Set(dv[i].x, dv[i].z, dv[i].y, dv[i].u, dv[i].v);
|
||||
}
|
||||
di->AddDecal(&gldecal);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -312,9 +289,8 @@ void GLWall::ProcessDecals(HWDrawInfo *di)
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void FDrawInfo::DrawDecal(GLWall *__wall, DBaseDecal *__decal)
|
||||
void FDrawInfo::DrawDecal(GLDecal *gldecal)
|
||||
{
|
||||
GLDecal *gldecal;
|
||||
auto wall = gldecal->wall;
|
||||
auto decal = gldecal->decal;
|
||||
auto tex = gldecal->gltexture;
|
||||
|
@ -401,29 +377,42 @@ void FDrawInfo::DrawDecal(GLWall *__wall, DBaseDecal *__decal)
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void FDrawInfo::DoDrawDecals(GLWall *wall)
|
||||
void FDrawInfo::DrawDecals()
|
||||
{
|
||||
if (wall->seg->sidedef && wall->seg->sidedef->AttachedDecals)
|
||||
GLWall *wall = nullptr;
|
||||
for (auto gldecal : decals[0])
|
||||
{
|
||||
if (wall->lightlist != nullptr)
|
||||
if (gldecal->wall != wall)
|
||||
{
|
||||
gl_RenderState.EnableSplit(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
mDrawer->SetFog(wall->lightlevel, wall->rellight + getExtraLight(), &wall->Colormap, false);
|
||||
wall = gldecal->wall;
|
||||
if (wall->lightlist != nullptr)
|
||||
{
|
||||
gl_RenderState.EnableSplit(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_RenderState.EnableSplit(false);
|
||||
mDrawer->SetFog(wall->lightlevel, wall->rellight + getExtraLight(), &wall->Colormap, false);
|
||||
}
|
||||
}
|
||||
DrawDecal(gldecal);
|
||||
}
|
||||
if (wall && wall->lightlist != nullptr) gl_RenderState.EnableSplit(false);
|
||||
}
|
||||
|
||||
DBaseDecal *decal = wall->seg->sidedef->AttachedDecals;
|
||||
while (decal)
|
||||
//==========================================================================
|
||||
//
|
||||
// This list will never get long, so this code should be ok.
|
||||
//
|
||||
//==========================================================================
|
||||
void FDrawInfo::DrawDecalsForMirror(GLWall *wall)
|
||||
{
|
||||
mDrawer->SetFog(wall->lightlevel, wall->rellight + getExtraLight(), &wall->Colormap, false);
|
||||
for (auto gldecal : decals[1])
|
||||
{
|
||||
if (gldecal->wall == wall)
|
||||
{
|
||||
DrawDecal(wall, decal);
|
||||
decal = decal->WallNext;
|
||||
}
|
||||
|
||||
if (wall->lightlist != nullptr)
|
||||
{
|
||||
gl_RenderState.EnableSplit(false);
|
||||
DrawDecal(gldecal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -867,19 +867,6 @@ void GLDrawList::DrawFlats(int pass)
|
|||
RenderFlat.Unclock();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void GLDrawList::DrawDecals()
|
||||
{
|
||||
for(unsigned i=0;i<drawitems.Size();i++)
|
||||
{
|
||||
gl_drawinfo->DoDrawDecals(walls[drawitems[i].index]);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Sorting the drawitems first by texture and then by light level.
|
||||
|
@ -952,7 +939,6 @@ GLSprite *GLDrawList::NewSprite()
|
|||
return sprite;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Try to reuse the lists as often as possible as they contain resources that
|
||||
|
@ -1033,6 +1019,8 @@ void FDrawInfo::StartScene()
|
|||
{
|
||||
for (int i = 0; i < GLLDL_TYPES; i++) dldrawlists[i].Reset();
|
||||
}
|
||||
decals[0].Clear();
|
||||
decals[1].Clear();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1323,3 +1311,11 @@ std::pair<FFlatVertex *, unsigned int> FDrawInfo::AllocVertices(unsigned int cou
|
|||
auto p = GLRenderer->mVBO->Alloc(count, &index);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -158,7 +158,6 @@ public:
|
|||
void Draw(int pass, bool trans = false);
|
||||
void DrawWalls(int pass);
|
||||
void DrawFlats(int pass);
|
||||
void DrawDecals();
|
||||
|
||||
GLDrawList * next;
|
||||
} ;
|
||||
|
@ -172,6 +171,7 @@ struct FDrawInfo : public HWDrawInfo
|
|||
|
||||
FDrawInfo * next;
|
||||
GLDrawList drawlists[GLDL_TYPES];
|
||||
TArray<GLDecal *> decals[2]; // the second slot is for mirrors which get rendered in a separate pass.
|
||||
GLDrawList *dldrawlists = NULL; // only gets allocated when needed.
|
||||
|
||||
FDrawInfo();
|
||||
|
@ -179,6 +179,7 @@ struct FDrawInfo : public HWDrawInfo
|
|||
|
||||
void AddWall(GLWall *wall) override;
|
||||
void AddMirrorSurface(GLWall *w) override;
|
||||
GLDecal *AddDecal(bool onmirror) override;
|
||||
void AddPortal(GLWall *w, int portaltype) override;
|
||||
|
||||
void ProcessActorsInPortal(FLinePortalSpan *glport) override;
|
||||
|
@ -189,10 +190,10 @@ struct FDrawInfo : public HWDrawInfo
|
|||
void RenderFogBoundaryCompat(GLWall *wall);
|
||||
void RenderLightsCompat(GLWall *wall, int pass);
|
||||
|
||||
void DrawDecal(GLWall *wall, DBaseDecal *decal);
|
||||
void DoDrawDecals(GLWall *wall);
|
||||
void DrawDecal(GLDecal *gldecal);
|
||||
void DrawDecals();
|
||||
void DrawDecalsForMirror(GLWall *wall);
|
||||
|
||||
|
||||
void StartScene();
|
||||
void SetupFloodStencil(wallseg * ws);
|
||||
void ClearFloodStencil(wallseg * ws);
|
||||
|
|
|
@ -375,15 +375,7 @@ void GLSceneDrawer::RenderScene(int recursion)
|
|||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(-1.0f, -128.0f);
|
||||
glDepthMask(false);
|
||||
|
||||
// this is the only geometry type on which decals can possibly appear
|
||||
gl_drawinfo->drawlists[GLDL_PLAINWALLS].DrawDecals();
|
||||
if (gl.legacyMode)
|
||||
{
|
||||
// also process the render lists with walls and dynamic lights
|
||||
gl_drawinfo->dldrawlists[GLLDL_WALLS_PLAIN].DrawDecals();
|
||||
gl_drawinfo->dldrawlists[GLLDL_WALLS_FOG].DrawDecals();
|
||||
}
|
||||
gl_drawinfo->DrawDecals();
|
||||
|
||||
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||
|
||||
|
@ -434,9 +426,10 @@ void GLSceneDrawer::RenderTranslucent()
|
|||
gl_drawinfo->drawlists[GLDL_TRANSLUCENT].DrawSorted();
|
||||
gl_RenderState.EnableBrightmap(false);
|
||||
|
||||
glDepthMask(true);
|
||||
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.5f);
|
||||
glDepthMask(true);
|
||||
|
||||
RenderAll.Unclock();
|
||||
}
|
||||
|
||||
|
|
|
@ -139,13 +139,14 @@ void FDrawInfo::RenderMirrorSurface(GLWall *wall)
|
|||
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.
|
||||
// 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)
|
||||
{
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(-1.0f, -128.0f);
|
||||
glDepthMask(false);
|
||||
gl_drawinfo->DoDrawDecals(wall);
|
||||
gl_drawinfo->DrawDecalsForMirror(wall);
|
||||
glDepthMask(true);
|
||||
glPolygonOffset(0.0f, 0.0f);
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
|
|
|
@ -128,7 +128,7 @@ public:
|
|||
virtual void AddWall(GLWall *w) = 0;
|
||||
virtual void AddPortal(GLWall *w, int portaltype) = 0;
|
||||
virtual void AddMirrorSurface(GLWall *w) = 0;
|
||||
virtual void AddDecal(GLDecal *d) = 0;
|
||||
virtual GLDecal *AddDecal(bool onmirror) = 0;
|
||||
virtual void ProcessActorsInPortal(FLinePortalSpan *glport) = 0;
|
||||
virtual std::pair<FFlatVertex *, unsigned int> AllocVertices(unsigned int count) = 0;
|
||||
|
||||
|
|
|
@ -281,6 +281,32 @@ public:
|
|||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
struct DecalVertex
|
||||
{
|
||||
float x, y, z;
|
||||
float u, v;
|
||||
};
|
||||
|
||||
struct GLDecal
|
||||
{
|
||||
FMaterial *gltexture;
|
||||
GLWall *wall;
|
||||
DBaseDecal *decal;
|
||||
DecalVertex dv[4];
|
||||
float zcenter;
|
||||
unsigned int vertindex;
|
||||
|
||||
int light;
|
||||
int rel;
|
||||
float a;
|
||||
FColormap colormap;
|
||||
|
||||
};
|
||||
|
||||
|
||||
inline float Dist2(float x1,float y1,float x2,float y2)
|
||||
{
|
||||
return sqrtf((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "p_maputl.h"
|
||||
#include "doomdata.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "actorinlines.h"
|
||||
#include "hwrenderer/dynlights/hw_dynlightdata.h"
|
||||
#include "hwrenderer/textures/hw_material.h"
|
||||
#include "hwrenderer/utility/hw_cvars.h"
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "tarray.h"
|
||||
|
||||
typedef TMap<int, bool> SpriteHits;
|
||||
class FTexture;
|
||||
|
||||
class IHardwareTexture
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue