mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-02-25 13:21:33 +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;
|
static const unsigned int BUFFER_SIZE_TO_USE = 1999500;
|
||||||
|
|
||||||
public:
|
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(int width, int height);
|
||||||
~FFlatVertexBuffer();
|
~FFlatVertexBuffer();
|
||||||
|
|
|
@ -21,7 +21,7 @@ class FSkyVertexBuffer;
|
||||||
class OpenGLFrameBuffer;
|
class OpenGLFrameBuffer;
|
||||||
struct FDrawInfo;
|
struct FDrawInfo;
|
||||||
class FShaderManager;
|
class FShaderManager;
|
||||||
class GLPortal;
|
class HWPortal;
|
||||||
class FLightBuffer;
|
class FLightBuffer;
|
||||||
class FSamplerManager;
|
class FSamplerManager;
|
||||||
class DPSprite;
|
class DPSprite;
|
||||||
|
|
|
@ -314,7 +314,7 @@ void FDrawInfo::DrawHUDModel(HUDSprite *huds, FRenderState &state)
|
||||||
|
|
||||||
void FDrawInfo::RenderPortal(HWPortal *p, bool usestencil)
|
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);
|
gp->SetupStencil(this, gl_RenderState, usestencil);
|
||||||
auto new_di = StartDrawInfo(Viewpoint, &VPUniforms);
|
auto new_di = StartDrawInfo(Viewpoint, &VPUniforms);
|
||||||
new_di->mCurrentPortal = gp;
|
new_di->mCurrentPortal = gp;
|
||||||
|
|
|
@ -56,153 +56,6 @@
|
||||||
|
|
||||||
EXTERN_CVAR(Int, r_mirror_recursions)
|
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)
|
GLHorizonPortal::GLHorizonPortal(FPortalSceneState *s, GLHorizonInfo * pt, FRenderViewpoint &vp, bool local)
|
||||||
: GLPortal(s, local)
|
: HWPortal(s, local)
|
||||||
{
|
{
|
||||||
origin = pt;
|
origin = pt;
|
||||||
|
|
||||||
|
|
|
@ -46,38 +46,11 @@
|
||||||
|
|
||||||
struct GLEEHorizonPortal;
|
struct GLEEHorizonPortal;
|
||||||
|
|
||||||
class GLPortal : public HWPortal
|
class GLScenePortal : 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
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HWScenePortalBase *mScene;
|
HWScenePortalBase *mScene;
|
||||||
GLScenePortal(FPortalSceneState *state, HWScenePortalBase *handler) : GLPortal(state)
|
GLScenePortal(FPortalSceneState *state, HWScenePortalBase *handler) : HWPortal(state, false)
|
||||||
{
|
{
|
||||||
mScene = handler;
|
mScene = handler;
|
||||||
handler->SetOwner(this);
|
handler->SetOwner(this);
|
||||||
|
@ -101,7 +74,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct GLSkyPortal : public GLPortal
|
struct GLSkyPortal : public HWPortal
|
||||||
{
|
{
|
||||||
GLSkyInfo * origin;
|
GLSkyInfo * origin;
|
||||||
friend struct GLEEHorizonPortal;
|
friend struct GLEEHorizonPortal;
|
||||||
|
@ -117,14 +90,14 @@ public:
|
||||||
|
|
||||||
|
|
||||||
GLSkyPortal(FPortalSceneState *state, GLSkyInfo * pt, bool local = false)
|
GLSkyPortal(FPortalSceneState *state, GLSkyInfo * pt, bool local = false)
|
||||||
: GLPortal(state, local)
|
: HWPortal(state, local)
|
||||||
{
|
{
|
||||||
origin=pt;
|
origin=pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GLHorizonPortal : public GLPortal
|
struct GLHorizonPortal : public HWPortal
|
||||||
{
|
{
|
||||||
GLHorizonInfo * origin;
|
GLHorizonInfo * origin;
|
||||||
unsigned int voffset;
|
unsigned int voffset;
|
||||||
|
@ -143,7 +116,7 @@ public:
|
||||||
GLHorizonPortal(FPortalSceneState *state, GLHorizonInfo * pt, FRenderViewpoint &vp, bool local = false);
|
GLHorizonPortal(FPortalSceneState *state, GLHorizonInfo * pt, FRenderViewpoint &vp, bool local = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GLEEHorizonPortal : public GLPortal
|
struct GLEEHorizonPortal : public HWPortal
|
||||||
{
|
{
|
||||||
FSectorPortal * portal;
|
FSectorPortal * portal;
|
||||||
|
|
||||||
|
@ -156,7 +129,7 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
GLEEHorizonPortal(FPortalSceneState *state, FSectorPortal *pt) : GLPortal(state)
|
GLEEHorizonPortal(FPortalSceneState *state, FSectorPortal *pt) : HWPortal(state, false)
|
||||||
{
|
{
|
||||||
portal=pt;
|
portal=pt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,7 +230,7 @@ void FDrawInfo::RenderTranslucent()
|
||||||
//
|
//
|
||||||
// gl_drawscene - this function renders the scene from the current
|
// gl_drawscene - this function renders the scene from the current
|
||||||
// viewpoint, including mirrors and skyboxes and other portals
|
// 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!
|
// stencil, z-buffer and the projection matrix intact!
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
|
@ -147,7 +147,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
friend struct HWDrawList;
|
friend struct HWDrawList;
|
||||||
friend class GLPortal;
|
friend class HWPortal;
|
||||||
|
|
||||||
vertex_t * vertexes[2]; // required for polygon splitting
|
vertex_t * vertexes[2]; // required for polygon splitting
|
||||||
FMaterial *gltexture;
|
FMaterial *gltexture;
|
||||||
|
|
|
@ -32,6 +32,9 @@
|
||||||
#include "hw_clipper.h"
|
#include "hw_clipper.h"
|
||||||
#include "actor.h"
|
#include "actor.h"
|
||||||
#include "g_levellocals.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(Int, r_mirror_recursions)
|
||||||
EXTERN_CVAR(Bool, gl_portals)
|
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
|
#pragma once
|
||||||
|
|
||||||
#include "portal.h"
|
#include "portal.h"
|
||||||
|
#include "actor.h"
|
||||||
#include "hw_drawinfo.h"
|
#include "hw_drawinfo.h"
|
||||||
#include "hw_drawstructs.h"
|
#include "hw_drawstructs.h"
|
||||||
#include "hwrenderer/textures/hw_material.h"
|
#include "hwrenderer/textures/hw_material.h"
|
||||||
|
@ -40,11 +41,28 @@ struct FPortalSceneState;
|
||||||
class HWPortal
|
class HWPortal
|
||||||
{
|
{
|
||||||
friend struct FPortalSceneState;
|
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:
|
public:
|
||||||
FPortalSceneState * mState;
|
FPortalSceneState * mState;
|
||||||
TArray<GLWall> lines;
|
TArray<GLWall> lines;
|
||||||
|
|
||||||
HWPortal(FPortalSceneState *s, bool local);
|
HWPortal(FPortalSceneState *s, bool local);
|
||||||
|
void SetupStencil(HWDrawInfo *di, FRenderState &state, bool usestencil);
|
||||||
|
void RemoveStencil(HWDrawInfo *di, FRenderState &state, bool usestencil);
|
||||||
|
|
||||||
virtual ~HWPortal() {}
|
virtual ~HWPortal() {}
|
||||||
virtual void * GetSource() const = 0; // GetSource MUST be implemented!
|
virtual void * GetSource() const = 0; // GetSource MUST be implemented!
|
||||||
virtual const char *GetName() = 0;
|
virtual const char *GetName() = 0;
|
||||||
|
|
Loading…
Reference in a new issue