mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-10 14:51:46 +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/scene/gl_scenedrawer.h"
|
||||||
#include "gl/renderer/gl_quaddrawer.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)
|
void GLWall::ProcessDecal(HWDrawInfo *di, DBaseDecal *decal)
|
||||||
{
|
{
|
||||||
line_t * line = seg->linedef;
|
line_t * line = seg->linedef;
|
||||||
|
@ -70,11 +48,11 @@ void GLWall::ProcessDecal(HWDrawInfo *di, DBaseDecal *decal)
|
||||||
float zpos;
|
float zpos;
|
||||||
bool flipx, flipy;
|
bool flipx, flipy;
|
||||||
FTextureID decalTile;
|
FTextureID decalTile;
|
||||||
GLDecal gldecal;
|
|
||||||
|
|
||||||
|
|
||||||
if (decal->RenderFlags & RF_INVISIBLE) return;
|
if (decal->RenderFlags & RF_INVISIBLE) return;
|
||||||
if (type == RENDERWALL_FFBLOCK && gltexture->isMasked()) return; // No decals on 3D floors with transparent textures.
|
if (type == RENDERWALL_FFBLOCK && gltexture->isMasked()) return; // No decals on 3D floors with transparent textures.
|
||||||
|
if (seg == nullptr) return;
|
||||||
|
|
||||||
|
|
||||||
decalTile = decal->PicNum;
|
decalTile = decal->PicNum;
|
||||||
|
@ -139,7 +117,7 @@ void GLWall::ProcessDecal(HWDrawInfo *di, DBaseDecal *decal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&gldecal, 0, sizeof(gldecal));
|
GLDecal &gldecal = *di->AddDecal(type == RENDERWALL_MIRRORSURFACE);
|
||||||
gldecal.gltexture = FMaterial::ValidateTexture(texture, true);
|
gldecal.gltexture = FMaterial::ValidateTexture(texture, true);
|
||||||
gldecal.wall = this;
|
gldecal.wall = this;
|
||||||
gldecal.decal = decal;
|
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);
|
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 wall = gldecal->wall;
|
||||||
auto decal = gldecal->decal;
|
auto decal = gldecal->decal;
|
||||||
auto tex = gldecal->gltexture;
|
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 (gldecal->wall != wall)
|
||||||
|
{
|
||||||
|
wall = gldecal->wall;
|
||||||
if (wall->lightlist != nullptr)
|
if (wall->lightlist != nullptr)
|
||||||
{
|
{
|
||||||
gl_RenderState.EnableSplit(true);
|
gl_RenderState.EnableSplit(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
gl_RenderState.EnableSplit(false);
|
||||||
mDrawer->SetFog(wall->lightlevel, wall->rellight + getExtraLight(), &wall->Colormap, 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)
|
||||||
{
|
{
|
||||||
DrawDecal(wall, decal);
|
mDrawer->SetFog(wall->lightlevel, wall->rellight + getExtraLight(), &wall->Colormap, false);
|
||||||
decal = decal->WallNext;
|
for (auto gldecal : decals[1])
|
||||||
}
|
|
||||||
|
|
||||||
if (wall->lightlist != nullptr)
|
|
||||||
{
|
{
|
||||||
gl_RenderState.EnableSplit(false);
|
if (gldecal->wall == wall)
|
||||||
|
{
|
||||||
|
DrawDecal(gldecal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -867,19 +867,6 @@ void GLDrawList::DrawFlats(int pass)
|
||||||
RenderFlat.Unclock();
|
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.
|
// Sorting the drawitems first by texture and then by light level.
|
||||||
|
@ -952,7 +939,6 @@ GLSprite *GLDrawList::NewSprite()
|
||||||
return sprite;
|
return sprite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Try to reuse the lists as often as possible as they contain resources that
|
// 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();
|
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);
|
auto p = GLRenderer->mVBO->Alloc(count, &index);
|
||||||
return std::make_pair(p, 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 Draw(int pass, bool trans = false);
|
||||||
void DrawWalls(int pass);
|
void DrawWalls(int pass);
|
||||||
void DrawFlats(int pass);
|
void DrawFlats(int pass);
|
||||||
void DrawDecals();
|
|
||||||
|
|
||||||
GLDrawList * next;
|
GLDrawList * next;
|
||||||
} ;
|
} ;
|
||||||
|
@ -172,6 +171,7 @@ struct FDrawInfo : public HWDrawInfo
|
||||||
|
|
||||||
FDrawInfo * next;
|
FDrawInfo * next;
|
||||||
GLDrawList drawlists[GLDL_TYPES];
|
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.
|
GLDrawList *dldrawlists = NULL; // only gets allocated when needed.
|
||||||
|
|
||||||
FDrawInfo();
|
FDrawInfo();
|
||||||
|
@ -179,6 +179,7 @@ struct FDrawInfo : public HWDrawInfo
|
||||||
|
|
||||||
void AddWall(GLWall *wall) override;
|
void AddWall(GLWall *wall) override;
|
||||||
void AddMirrorSurface(GLWall *w) override;
|
void AddMirrorSurface(GLWall *w) override;
|
||||||
|
GLDecal *AddDecal(bool onmirror) override;
|
||||||
void AddPortal(GLWall *w, int portaltype) override;
|
void AddPortal(GLWall *w, int portaltype) override;
|
||||||
|
|
||||||
void ProcessActorsInPortal(FLinePortalSpan *glport) override;
|
void ProcessActorsInPortal(FLinePortalSpan *glport) override;
|
||||||
|
@ -189,9 +190,9 @@ struct FDrawInfo : public HWDrawInfo
|
||||||
void RenderFogBoundaryCompat(GLWall *wall);
|
void RenderFogBoundaryCompat(GLWall *wall);
|
||||||
void RenderLightsCompat(GLWall *wall, int pass);
|
void RenderLightsCompat(GLWall *wall, int pass);
|
||||||
|
|
||||||
void DrawDecal(GLWall *wall, DBaseDecal *decal);
|
void DrawDecal(GLDecal *gldecal);
|
||||||
void DoDrawDecals(GLWall *wall);
|
void DrawDecals();
|
||||||
|
void DrawDecalsForMirror(GLWall *wall);
|
||||||
|
|
||||||
void StartScene();
|
void StartScene();
|
||||||
void SetupFloodStencil(wallseg * ws);
|
void SetupFloodStencil(wallseg * ws);
|
||||||
|
|
|
@ -375,15 +375,7 @@ void GLSceneDrawer::RenderScene(int recursion)
|
||||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||||
glPolygonOffset(-1.0f, -128.0f);
|
glPolygonOffset(-1.0f, -128.0f);
|
||||||
glDepthMask(false);
|
glDepthMask(false);
|
||||||
|
gl_drawinfo->DrawDecals();
|
||||||
// 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_RenderState.SetTextureMode(TM_MODULATE);
|
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||||
|
|
||||||
|
@ -434,9 +426,10 @@ void GLSceneDrawer::RenderTranslucent()
|
||||||
gl_drawinfo->drawlists[GLDL_TRANSLUCENT].DrawSorted();
|
gl_drawinfo->drawlists[GLDL_TRANSLUCENT].DrawSorted();
|
||||||
gl_RenderState.EnableBrightmap(false);
|
gl_RenderState.EnableBrightmap(false);
|
||||||
|
|
||||||
glDepthMask(true);
|
|
||||||
|
|
||||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.5f);
|
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.5f);
|
||||||
|
glDepthMask(true);
|
||||||
|
|
||||||
RenderAll.Unclock();
|
RenderAll.Unclock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -139,13 +139,14 @@ void FDrawInfo::RenderMirrorSurface(GLWall *wall)
|
||||||
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
|
||||||
// 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)
|
if (wall->seg->sidedef->AttachedDecals)
|
||||||
{
|
{
|
||||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||||
glPolygonOffset(-1.0f, -128.0f);
|
glPolygonOffset(-1.0f, -128.0f);
|
||||||
glDepthMask(false);
|
glDepthMask(false);
|
||||||
gl_drawinfo->DoDrawDecals(wall);
|
gl_drawinfo->DrawDecalsForMirror(wall);
|
||||||
glDepthMask(true);
|
glDepthMask(true);
|
||||||
glPolygonOffset(0.0f, 0.0f);
|
glPolygonOffset(0.0f, 0.0f);
|
||||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||||
|
|
|
@ -128,7 +128,7 @@ public:
|
||||||
virtual void AddWall(GLWall *w) = 0;
|
virtual void AddWall(GLWall *w) = 0;
|
||||||
virtual void AddPortal(GLWall *w, int portaltype) = 0;
|
virtual void AddPortal(GLWall *w, int portaltype) = 0;
|
||||||
virtual void AddMirrorSurface(GLWall *w) = 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 void ProcessActorsInPortal(FLinePortalSpan *glport) = 0;
|
||||||
virtual std::pair<FFlatVertex *, unsigned int> AllocVertices(unsigned int count) = 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)
|
inline float Dist2(float x1,float y1,float x2,float y2)
|
||||||
{
|
{
|
||||||
return sqrtf((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
|
return sqrtf((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "p_maputl.h"
|
#include "p_maputl.h"
|
||||||
#include "doomdata.h"
|
#include "doomdata.h"
|
||||||
#include "g_levellocals.h"
|
#include "g_levellocals.h"
|
||||||
|
#include "actorinlines.h"
|
||||||
#include "hwrenderer/dynlights/hw_dynlightdata.h"
|
#include "hwrenderer/dynlights/hw_dynlightdata.h"
|
||||||
#include "hwrenderer/textures/hw_material.h"
|
#include "hwrenderer/textures/hw_material.h"
|
||||||
#include "hwrenderer/utility/hw_cvars.h"
|
#include "hwrenderer/utility/hw_cvars.h"
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "tarray.h"
|
||||||
|
|
||||||
typedef TMap<int, bool> SpriteHits;
|
typedef TMap<int, bool> SpriteHits;
|
||||||
|
class FTexture;
|
||||||
|
|
||||||
class IHardwareTexture
|
class IHardwareTexture
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue