mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 15:02:01 +00:00
- merged GLPortal into HWPortal after all direct OpenGL dependencies have been removed.
This commit is contained in:
parent
d757efde96
commit
c76c4b77ec
9 changed files with 183 additions and 196 deletions
|
@ -108,16 +108,6 @@ class FFlatVertexBuffer : public FVertexBuffer, public FFlatVertexGenerator
|
|||
static const unsigned int BUFFER_SIZE_TO_USE = 1999500;
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
QUAD_INDEX = 0,
|
||||
FULLSCREEN_INDEX = 4,
|
||||
PRESENT_INDEX = 8,
|
||||
STENCILTOP_INDEX = 12,
|
||||
STENCILBOTTOM_INDEX = 16,
|
||||
|
||||
NUM_RESERVED = 20
|
||||
};
|
||||
|
||||
FFlatVertexBuffer(int width, int height);
|
||||
~FFlatVertexBuffer();
|
||||
|
|
|
@ -21,7 +21,7 @@ class FSkyVertexBuffer;
|
|||
class OpenGLFrameBuffer;
|
||||
struct FDrawInfo;
|
||||
class FShaderManager;
|
||||
class GLPortal;
|
||||
class HWPortal;
|
||||
class FLightBuffer;
|
||||
class FSamplerManager;
|
||||
class DPSprite;
|
||||
|
|
|
@ -314,7 +314,7 @@ void FDrawInfo::DrawHUDModel(HUDSprite *huds, FRenderState &state)
|
|||
|
||||
void FDrawInfo::RenderPortal(HWPortal *p, bool usestencil)
|
||||
{
|
||||
auto gp = static_cast<GLPortal *>(p);
|
||||
auto gp = static_cast<HWPortal *>(p);
|
||||
gp->SetupStencil(this, gl_RenderState, usestencil);
|
||||
auto new_di = StartDrawInfo(Viewpoint, &VPUniforms);
|
||||
new_di->mCurrentPortal = gp;
|
||||
|
|
|
@ -56,153 +56,6 @@
|
|||
|
||||
EXTERN_CVAR(Int, r_mirror_recursions)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// DrawPortalStencil
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void GLPortal::DrawPortalStencil(HWDrawInfo *di, FRenderState &state, int pass)
|
||||
{
|
||||
if (mPrimIndices.Size() == 0)
|
||||
{
|
||||
mPrimIndices.Resize(2 * lines.Size());
|
||||
|
||||
for (unsigned int i = 0; i < lines.Size(); i++)
|
||||
{
|
||||
mPrimIndices[i * 2] = lines[i].vertindex;
|
||||
mPrimIndices[i * 2 + 1] = lines[i].vertcount;
|
||||
}
|
||||
}
|
||||
for (unsigned int i = 0; i < mPrimIndices.Size(); i += 2)
|
||||
{
|
||||
di->Draw(DT_TriangleFan, state, mPrimIndices[i], mPrimIndices[i + 1], i==0);
|
||||
}
|
||||
if (NeedCap() && lines.Size() > 1)
|
||||
{
|
||||
// The cap's depth handling needs special treatment so that it won't block further portal caps.
|
||||
if (pass == STP_DepthRestore) di->SetDepthRange(1, 1);
|
||||
di->Draw(DT_TriangleFan, state, FFlatVertexBuffer::STENCILTOP_INDEX, 4);
|
||||
di->Draw(DT_TriangleFan, state, FFlatVertexBuffer::STENCILBOTTOM_INDEX, 4);
|
||||
if (pass == STP_DepthRestore) di->SetDepthRange(0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Start
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void GLPortal::SetupStencil(HWDrawInfo *di, FRenderState &state, bool usestencil)
|
||||
{
|
||||
Clocker c(PortalAll);
|
||||
|
||||
rendered_portals++;
|
||||
if (usestencil)
|
||||
{
|
||||
// Create stencil
|
||||
state.SetEffect(EFF_STENCIL);
|
||||
state.EnableTexture(false);
|
||||
state.ResetColor();
|
||||
|
||||
if (NeedDepthBuffer())
|
||||
{
|
||||
di->SetStencil(0, SOP_Increment, SF_ColorMaskOff | SF_DepthMaskOff);
|
||||
di->SetDepthFunc(DF_Less);
|
||||
DrawPortalStencil(di, state, STP_Stencil);
|
||||
|
||||
// Clear Z-buffer
|
||||
di->SetStencil(1, SOP_Keep, SF_ColorMaskOff);
|
||||
di->SetDepthRange(1, 1);
|
||||
di->SetDepthFunc(DF_Always);
|
||||
DrawPortalStencil(di, state, STP_DepthClear);
|
||||
|
||||
// set normal drawing mode
|
||||
state.EnableTexture(true);
|
||||
di->SetStencil(1, SOP_Keep, SF_AllOn);
|
||||
di->SetDepthRange(0, 1);
|
||||
di->SetDepthFunc(DF_Less);
|
||||
state.SetEffect(EFF_NONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No z-buffer is needed therefore we can skip all the complicated stuff that is involved
|
||||
// Note: We must draw the stencil with z-write enabled here because there is no second pass!
|
||||
di->SetStencil(0, SOP_Increment, SF_ColorMaskOff);
|
||||
di->SetDepthFunc(DF_Less);
|
||||
DrawPortalStencil(di, state, STP_AllInOne);
|
||||
|
||||
di->SetStencil(1, SOP_Keep, SF_DepthTestOff | SF_DepthMaskOff);
|
||||
state.EnableTexture(true);
|
||||
state.SetEffect(EFF_NONE);
|
||||
}
|
||||
|
||||
screen->stencilValue++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!NeedDepthBuffer())
|
||||
{
|
||||
di->SetStencil(0, SOP_Keep, SF_DepthTestOff | SF_DepthMaskOff);
|
||||
}
|
||||
}
|
||||
|
||||
// save viewpoint
|
||||
savedvisibility = di->Viewpoint.camera ? di->Viewpoint.camera->renderflags & RF_MAYBEINVISIBLE : ActorRenderFlags::FromInt(0);
|
||||
}
|
||||
|
||||
void GLPortal::RemoveStencil(HWDrawInfo *di, FRenderState &state, bool usestencil)
|
||||
{
|
||||
Clocker c(PortalAll);
|
||||
bool needdepth = NeedDepthBuffer();
|
||||
|
||||
// Restore the old view
|
||||
auto &vp = di->Viewpoint;
|
||||
if (vp.camera != nullptr) vp.camera->renderflags = (vp.camera->renderflags & ~RF_MAYBEINVISIBLE) | savedvisibility;
|
||||
|
||||
if (usestencil)
|
||||
{
|
||||
state.SetEffect(EFF_NONE);
|
||||
state.ResetColor();
|
||||
state.EnableTexture(false);
|
||||
|
||||
if (needdepth)
|
||||
{
|
||||
// first step: reset the depth buffer to max. depth
|
||||
di->SetStencil(0, SOP_Keep, SF_ColorMaskOff);
|
||||
di->SetDepthRange(1, 1); // always
|
||||
di->SetDepthFunc(DF_Always); // write the farthest depth value
|
||||
DrawPortalStencil(di, state, STP_DepthClear);
|
||||
}
|
||||
|
||||
// second step: restore the depth buffer to the previous values and reset the stencil
|
||||
di->SetStencil(0, SOP_Decrement, SF_ColorMaskOff);
|
||||
di->SetDepthRange(0, 1);
|
||||
di->SetDepthFunc(DF_LEqual);
|
||||
DrawPortalStencil(di, state, STP_DepthRestore);
|
||||
|
||||
state.EnableTexture(true);
|
||||
state.SetEffect(EFF_NONE);
|
||||
screen->stencilValue--;
|
||||
}
|
||||
else
|
||||
{
|
||||
state.ResetColor();
|
||||
state.SetEffect(EFF_STENCIL);
|
||||
state.EnableTexture(false);
|
||||
state.SetRenderStyle(STYLE_Source);
|
||||
|
||||
di->SetStencil(0, SOP_Keep, needdepth? SF_ColorMaskOff | SF_DepthClear : SF_ColorMaskOff);
|
||||
di->SetDepthRange(0, 1);
|
||||
di->SetDepthFunc(DF_LEqual);
|
||||
DrawPortalStencil(di, state, STP_DepthRestore);
|
||||
|
||||
state.SetEffect(EFF_NONE);
|
||||
state.EnableTexture(true);
|
||||
}
|
||||
di->SetStencil(0, SOP_Keep, SF_AllOn);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
|
@ -214,7 +67,7 @@ void GLPortal::RemoveStencil(HWDrawInfo *di, FRenderState &state, bool usestenci
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
GLHorizonPortal::GLHorizonPortal(FPortalSceneState *s, GLHorizonInfo * pt, FRenderViewpoint &vp, bool local)
|
||||
: GLPortal(s, local)
|
||||
: HWPortal(s, local)
|
||||
{
|
||||
origin = pt;
|
||||
|
||||
|
|
|
@ -46,38 +46,11 @@
|
|||
|
||||
struct GLEEHorizonPortal;
|
||||
|
||||
class GLPortal : public HWPortal
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
enum
|
||||
{
|
||||
STP_Stencil,
|
||||
STP_DepthClear,
|
||||
STP_DepthRestore,
|
||||
STP_AllInOne
|
||||
};
|
||||
void DrawPortalStencil(HWDrawInfo *di, FRenderState &state, int pass);
|
||||
|
||||
ActorRenderFlags savedvisibility;
|
||||
TArray<unsigned int> mPrimIndices;
|
||||
|
||||
public:
|
||||
void SetupStencil(HWDrawInfo *di, FRenderState &state, bool usestencil);
|
||||
void RemoveStencil(HWDrawInfo *di, FRenderState &state, bool usestencil);
|
||||
|
||||
protected:
|
||||
int level;
|
||||
|
||||
GLPortal(FPortalSceneState *state, bool local = false) : HWPortal(state, local) { }
|
||||
};
|
||||
|
||||
class GLScenePortal : public GLPortal
|
||||
class GLScenePortal : public HWPortal
|
||||
{
|
||||
public:
|
||||
HWScenePortalBase *mScene;
|
||||
GLScenePortal(FPortalSceneState *state, HWScenePortalBase *handler) : GLPortal(state)
|
||||
GLScenePortal(FPortalSceneState *state, HWScenePortalBase *handler) : HWPortal(state, false)
|
||||
{
|
||||
mScene = handler;
|
||||
handler->SetOwner(this);
|
||||
|
@ -101,7 +74,7 @@ public:
|
|||
};
|
||||
|
||||
|
||||
struct GLSkyPortal : public GLPortal
|
||||
struct GLSkyPortal : public HWPortal
|
||||
{
|
||||
GLSkyInfo * origin;
|
||||
friend struct GLEEHorizonPortal;
|
||||
|
@ -117,14 +90,14 @@ public:
|
|||
|
||||
|
||||
GLSkyPortal(FPortalSceneState *state, GLSkyInfo * pt, bool local = false)
|
||||
: GLPortal(state, local)
|
||||
: HWPortal(state, local)
|
||||
{
|
||||
origin=pt;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct GLHorizonPortal : public GLPortal
|
||||
struct GLHorizonPortal : public HWPortal
|
||||
{
|
||||
GLHorizonInfo * origin;
|
||||
unsigned int voffset;
|
||||
|
@ -143,7 +116,7 @@ public:
|
|||
GLHorizonPortal(FPortalSceneState *state, GLHorizonInfo * pt, FRenderViewpoint &vp, bool local = false);
|
||||
};
|
||||
|
||||
struct GLEEHorizonPortal : public GLPortal
|
||||
struct GLEEHorizonPortal : public HWPortal
|
||||
{
|
||||
FSectorPortal * portal;
|
||||
|
||||
|
@ -156,7 +129,7 @@ protected:
|
|||
|
||||
public:
|
||||
|
||||
GLEEHorizonPortal(FPortalSceneState *state, FSectorPortal *pt) : GLPortal(state)
|
||||
GLEEHorizonPortal(FPortalSceneState *state, FSectorPortal *pt) : HWPortal(state, false)
|
||||
{
|
||||
portal=pt;
|
||||
}
|
||||
|
|
|
@ -230,7 +230,7 @@ void FDrawInfo::RenderTranslucent()
|
|||
//
|
||||
// gl_drawscene - this function renders the scene from the current
|
||||
// viewpoint, including mirrors and skyboxes and other portals
|
||||
// It is assumed that the GLPortal::EndFrame returns with the
|
||||
// It is assumed that the HWPortal::EndFrame returns with the
|
||||
// stencil, z-buffer and the projection matrix intact!
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -147,7 +147,7 @@ public:
|
|||
};
|
||||
|
||||
friend struct HWDrawList;
|
||||
friend class GLPortal;
|
||||
friend class HWPortal;
|
||||
|
||||
vertex_t * vertexes[2]; // required for polygon splitting
|
||||
FMaterial *gltexture;
|
||||
|
|
|
@ -32,6 +32,9 @@
|
|||
#include "hw_clipper.h"
|
||||
#include "actor.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "hw_renderstate.h"
|
||||
#include "hwrenderer/data/flatvertices.h"
|
||||
#include "hwrenderer/utility/hw_clock.h"
|
||||
|
||||
EXTERN_CVAR(Int, r_mirror_recursions)
|
||||
EXTERN_CVAR(Bool, gl_portals)
|
||||
|
@ -156,6 +159,156 @@ void FPortalSceneState::RenderPortal(HWPortal *p, bool usestencil, HWDrawInfo *o
|
|||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// DrawPortalStencil
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void HWPortal::DrawPortalStencil(HWDrawInfo *di, FRenderState &state, int pass)
|
||||
{
|
||||
if (mPrimIndices.Size() == 0)
|
||||
{
|
||||
mPrimIndices.Resize(2 * lines.Size());
|
||||
|
||||
for (unsigned int i = 0; i < lines.Size(); i++)
|
||||
{
|
||||
mPrimIndices[i * 2] = lines[i].vertindex;
|
||||
mPrimIndices[i * 2 + 1] = lines[i].vertcount;
|
||||
}
|
||||
}
|
||||
for (unsigned int i = 0; i < mPrimIndices.Size(); i += 2)
|
||||
{
|
||||
di->Draw(DT_TriangleFan, state, mPrimIndices[i], mPrimIndices[i + 1], i == 0);
|
||||
}
|
||||
if (NeedCap() && lines.Size() > 1)
|
||||
{
|
||||
// The cap's depth handling needs special treatment so that it won't block further portal caps.
|
||||
if (pass == STP_DepthRestore) di->SetDepthRange(1, 1);
|
||||
di->Draw(DT_TriangleFan, state, FFlatVertexGenerator::STENCILTOP_INDEX, 4);
|
||||
di->Draw(DT_TriangleFan, state, FFlatVertexGenerator::STENCILBOTTOM_INDEX, 4);
|
||||
if (pass == STP_DepthRestore) di->SetDepthRange(0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Start
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void HWPortal::SetupStencil(HWDrawInfo *di, FRenderState &state, bool usestencil)
|
||||
{
|
||||
Clocker c(PortalAll);
|
||||
|
||||
rendered_portals++;
|
||||
if (usestencil)
|
||||
{
|
||||
// Create stencil
|
||||
state.SetEffect(EFF_STENCIL);
|
||||
state.EnableTexture(false);
|
||||
state.ResetColor();
|
||||
|
||||
if (NeedDepthBuffer())
|
||||
{
|
||||
di->SetStencil(0, SOP_Increment, SF_ColorMaskOff | SF_DepthMaskOff);
|
||||
di->SetDepthFunc(DF_Less);
|
||||
DrawPortalStencil(di, state, STP_Stencil);
|
||||
|
||||
// Clear Z-buffer
|
||||
di->SetStencil(1, SOP_Keep, SF_ColorMaskOff);
|
||||
di->SetDepthRange(1, 1);
|
||||
di->SetDepthFunc(DF_Always);
|
||||
DrawPortalStencil(di, state, STP_DepthClear);
|
||||
|
||||
// set normal drawing mode
|
||||
state.EnableTexture(true);
|
||||
di->SetStencil(1, SOP_Keep, SF_AllOn);
|
||||
di->SetDepthRange(0, 1);
|
||||
di->SetDepthFunc(DF_Less);
|
||||
state.SetEffect(EFF_NONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No z-buffer is needed therefore we can skip all the complicated stuff that is involved
|
||||
// Note: We must draw the stencil with z-write enabled here because there is no second pass!
|
||||
di->SetStencil(0, SOP_Increment, SF_ColorMaskOff);
|
||||
di->SetDepthFunc(DF_Less);
|
||||
DrawPortalStencil(di, state, STP_AllInOne);
|
||||
|
||||
di->SetStencil(1, SOP_Keep, SF_DepthTestOff | SF_DepthMaskOff);
|
||||
state.EnableTexture(true);
|
||||
state.SetEffect(EFF_NONE);
|
||||
}
|
||||
|
||||
screen->stencilValue++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!NeedDepthBuffer())
|
||||
{
|
||||
di->SetStencil(0, SOP_Keep, SF_DepthTestOff | SF_DepthMaskOff);
|
||||
}
|
||||
}
|
||||
|
||||
// save viewpoint
|
||||
savedvisibility = di->Viewpoint.camera ? di->Viewpoint.camera->renderflags & RF_MAYBEINVISIBLE : ActorRenderFlags::FromInt(0);
|
||||
}
|
||||
|
||||
void HWPortal::RemoveStencil(HWDrawInfo *di, FRenderState &state, bool usestencil)
|
||||
{
|
||||
Clocker c(PortalAll);
|
||||
bool needdepth = NeedDepthBuffer();
|
||||
|
||||
// Restore the old view
|
||||
auto &vp = di->Viewpoint;
|
||||
if (vp.camera != nullptr) vp.camera->renderflags = (vp.camera->renderflags & ~RF_MAYBEINVISIBLE) | savedvisibility;
|
||||
|
||||
if (usestencil)
|
||||
{
|
||||
state.SetEffect(EFF_NONE);
|
||||
state.ResetColor();
|
||||
state.EnableTexture(false);
|
||||
|
||||
if (needdepth)
|
||||
{
|
||||
// first step: reset the depth buffer to max. depth
|
||||
di->SetStencil(0, SOP_Keep, SF_ColorMaskOff);
|
||||
di->SetDepthRange(1, 1); // always
|
||||
di->SetDepthFunc(DF_Always); // write the farthest depth value
|
||||
DrawPortalStencil(di, state, STP_DepthClear);
|
||||
}
|
||||
|
||||
// second step: restore the depth buffer to the previous values and reset the stencil
|
||||
di->SetStencil(0, SOP_Decrement, SF_ColorMaskOff);
|
||||
di->SetDepthRange(0, 1);
|
||||
di->SetDepthFunc(DF_LEqual);
|
||||
DrawPortalStencil(di, state, STP_DepthRestore);
|
||||
|
||||
state.EnableTexture(true);
|
||||
state.SetEffect(EFF_NONE);
|
||||
screen->stencilValue--;
|
||||
}
|
||||
else
|
||||
{
|
||||
state.ResetColor();
|
||||
state.SetEffect(EFF_STENCIL);
|
||||
state.EnableTexture(false);
|
||||
state.SetRenderStyle(STYLE_Source);
|
||||
|
||||
di->SetStencil(0, SOP_Keep, needdepth ? SF_ColorMaskOff | SF_DepthClear : SF_ColorMaskOff);
|
||||
di->SetDepthRange(0, 1);
|
||||
di->SetDepthFunc(DF_LEqual);
|
||||
DrawPortalStencil(di, state, STP_DepthRestore);
|
||||
|
||||
state.SetEffect(EFF_NONE);
|
||||
state.EnableTexture(true);
|
||||
}
|
||||
di->SetStencil(0, SOP_Keep, SF_AllOn);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "portal.h"
|
||||
#include "actor.h"
|
||||
#include "hw_drawinfo.h"
|
||||
#include "hw_drawstructs.h"
|
||||
#include "hwrenderer/textures/hw_material.h"
|
||||
|
@ -40,11 +41,28 @@ struct FPortalSceneState;
|
|||
class HWPortal
|
||||
{
|
||||
friend struct FPortalSceneState;
|
||||
|
||||
enum
|
||||
{
|
||||
STP_Stencil,
|
||||
STP_DepthClear,
|
||||
STP_DepthRestore,
|
||||
STP_AllInOne
|
||||
};
|
||||
|
||||
ActorRenderFlags savedvisibility;
|
||||
TArray<unsigned int> mPrimIndices;
|
||||
|
||||
void DrawPortalStencil(HWDrawInfo *di, FRenderState &state, int pass);
|
||||
|
||||
public:
|
||||
FPortalSceneState * mState;
|
||||
TArray<GLWall> lines;
|
||||
|
||||
HWPortal(FPortalSceneState *s, bool local);
|
||||
void SetupStencil(HWDrawInfo *di, FRenderState &state, bool usestencil);
|
||||
void RemoveStencil(HWDrawInfo *di, FRenderState &state, bool usestencil);
|
||||
|
||||
virtual ~HWPortal() {}
|
||||
virtual void * GetSource() const = 0; // GetSource MUST be implemented!
|
||||
virtual const char *GetName() = 0;
|
||||
|
|
Loading…
Reference in a new issue