mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2025-02-21 11:01:36 +00:00
- made the static portal state a struct inside the Renderer object
This commit is contained in:
parent
009acf3fb2
commit
282fdac660
16 changed files with 420 additions and 430 deletions
|
@ -841,6 +841,7 @@ set( FASTMATH_SOURCES
|
||||||
hwrenderer/scene/hw_drawlist.cpp
|
hwrenderer/scene/hw_drawlist.cpp
|
||||||
hwrenderer/scene/hw_clipper.cpp
|
hwrenderer/scene/hw_clipper.cpp
|
||||||
hwrenderer/scene/hw_flats.cpp
|
hwrenderer/scene/hw_flats.cpp
|
||||||
|
hwrenderer/scene/hw_portal.cpp
|
||||||
hwrenderer/scene/hw_renderhacks.cpp
|
hwrenderer/scene/hw_renderhacks.cpp
|
||||||
hwrenderer/scene/hw_sky.cpp
|
hwrenderer/scene/hw_sky.cpp
|
||||||
hwrenderer/scene/hw_sprites.cpp
|
hwrenderer/scene/hw_sprites.cpp
|
||||||
|
|
|
@ -65,7 +65,7 @@ void FGLModelRenderer::BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, con
|
||||||
if (!(actor->RenderStyle == LegacyRenderStyles[STYLE_Normal]) && !(smf->flags & MDL_DONTCULLBACKFACES))
|
if (!(actor->RenderStyle == LegacyRenderStyles[STYLE_Normal]) && !(smf->flags & MDL_DONTCULLBACKFACES))
|
||||||
{
|
{
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
glFrontFace((mirrored ^ GLPortal::isMirrored()) ? GL_CCW : GL_CW);
|
glFrontFace((mirrored ^ GLRenderer->mPortalState.isMirrored()) ? GL_CCW : GL_CW);
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_RenderState.mModelMatrix = objectToWorldMatrix;
|
gl_RenderState.mModelMatrix = objectToWorldMatrix;
|
||||||
|
@ -91,7 +91,7 @@ void FGLModelRenderer::BeginDrawHUDModel(AActor *actor, const VSMatrix &objectTo
|
||||||
if (!(actor->RenderStyle == LegacyRenderStyles[STYLE_Normal]))
|
if (!(actor->RenderStyle == LegacyRenderStyles[STYLE_Normal]))
|
||||||
{
|
{
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
glFrontFace((mirrored ^ GLPortal::isMirrored()) ? GL_CW : GL_CCW);
|
glFrontFace((mirrored ^ GLRenderer->mPortalState.isMirrored()) ? GL_CW : GL_CCW);
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_RenderState.mModelMatrix = objectToWorldMatrix;
|
gl_RenderState.mModelMatrix = objectToWorldMatrix;
|
||||||
|
|
|
@ -173,7 +173,7 @@ void gl_SetFog(int lightlevel, int rellight, bool fullbright, const FColormap *c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make fog a little denser when inside a skybox
|
// Make fog a little denser when inside a skybox
|
||||||
if (GLPortal::inskybox) fogdensity+=fogdensity/2;
|
if (GLRenderer->mPortalState.inskybox) fogdensity+=fogdensity/2;
|
||||||
|
|
||||||
|
|
||||||
// no fog in enhanced vision modes!
|
// no fog in enhanced vision modes!
|
||||||
|
|
|
@ -150,6 +150,8 @@ void FGLRenderer::Initialize(int width, int height)
|
||||||
mCustomPostProcessShaders = new FCustomPostProcessShaders();
|
mCustomPostProcessShaders = new FCustomPostProcessShaders();
|
||||||
|
|
||||||
// needed for the core profile, because someone decided it was a good idea to remove the default VAO.
|
// needed for the core profile, because someone decided it was a good idea to remove the default VAO.
|
||||||
|
glGenQueries(1, &PortalQueryObject);
|
||||||
|
|
||||||
glGenVertexArrays(1, &mVAOID);
|
glGenVertexArrays(1, &mVAOID);
|
||||||
glBindVertexArray(mVAOID);
|
glBindVertexArray(mVAOID);
|
||||||
FGLDebug::LabelObject(GL_VERTEX_ARRAY, mVAOID, "FGLRenderer.mVAOID");
|
FGLDebug::LabelObject(GL_VERTEX_ARRAY, mVAOID, "FGLRenderer.mVAOID");
|
||||||
|
@ -164,14 +166,10 @@ void FGLRenderer::Initialize(int width, int height)
|
||||||
SetupLevel();
|
SetupLevel();
|
||||||
mShaderManager = new FShaderManager;
|
mShaderManager = new FShaderManager;
|
||||||
mSamplerManager = new FSamplerManager;
|
mSamplerManager = new FSamplerManager;
|
||||||
|
|
||||||
GLPortal::Initialize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FGLRenderer::~FGLRenderer()
|
FGLRenderer::~FGLRenderer()
|
||||||
{
|
{
|
||||||
GLPortal::Shutdown();
|
|
||||||
|
|
||||||
FlushModels();
|
FlushModels();
|
||||||
AActor::DeleteAllAttachedLights();
|
AActor::DeleteAllAttachedLights();
|
||||||
FMaterial::FlushAll();
|
FMaterial::FlushAll();
|
||||||
|
@ -186,6 +184,8 @@ FGLRenderer::~FGLRenderer()
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
glDeleteVertexArrays(1, &mVAOID);
|
glDeleteVertexArrays(1, &mVAOID);
|
||||||
}
|
}
|
||||||
|
if (PortalQueryObject != 0) glDeleteQueries(1, &PortalQueryObject);
|
||||||
|
|
||||||
if (swdrawer) delete swdrawer;
|
if (swdrawer) delete swdrawer;
|
||||||
if (mBuffers) delete mBuffers;
|
if (mBuffers) delete mBuffers;
|
||||||
if (mPresentShader) delete mPresentShader;
|
if (mPresentShader) delete mPresentShader;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "vectors.h"
|
#include "vectors.h"
|
||||||
#include "r_renderer.h"
|
#include "r_renderer.h"
|
||||||
#include "r_data/matrix.h"
|
#include "r_data/matrix.h"
|
||||||
|
#include "hwrenderer/scene/hw_portal.h"
|
||||||
#include "gl/dynlights/gl_shadowmap.h"
|
#include "gl/dynlights/gl_shadowmap.h"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
@ -73,6 +74,8 @@ public:
|
||||||
FSamplerManager *mSamplerManager;
|
FSamplerManager *mSamplerManager;
|
||||||
unsigned int mFBID;
|
unsigned int mFBID;
|
||||||
unsigned int mVAOID;
|
unsigned int mVAOID;
|
||||||
|
unsigned int PortalQueryObject;
|
||||||
|
|
||||||
int mOldFBID;
|
int mOldFBID;
|
||||||
|
|
||||||
FGLRenderBuffers *mBuffers;
|
FGLRenderBuffers *mBuffers;
|
||||||
|
@ -110,6 +113,8 @@ public:
|
||||||
FLightBuffer *mLights;
|
FLightBuffer *mLights;
|
||||||
SWSceneDrawer *swdrawer = nullptr;
|
SWSceneDrawer *swdrawer = nullptr;
|
||||||
|
|
||||||
|
FPortalSceneState mPortalState;
|
||||||
|
|
||||||
bool buffersActive = false;
|
bool buffersActive = false;
|
||||||
|
|
||||||
float mSceneClearColor[3];
|
float mSceneClearColor[3];
|
||||||
|
|
|
@ -265,7 +265,7 @@ FDrawInfo *FDrawInfo::EndDrawInfo()
|
||||||
|
|
||||||
void FDrawInfo::SetupFloodStencil(wallseg * ws)
|
void FDrawInfo::SetupFloodStencil(wallseg * ws)
|
||||||
{
|
{
|
||||||
int recursion = GLPortal::GetRecursion();
|
int recursion = GLRenderer->mPortalState.GetRecursion();
|
||||||
|
|
||||||
// Create stencil
|
// Create stencil
|
||||||
glStencilFunc(GL_EQUAL, recursion, ~0); // create stencil
|
glStencilFunc(GL_EQUAL, recursion, ~0); // create stencil
|
||||||
|
@ -297,7 +297,7 @@ void FDrawInfo::SetupFloodStencil(wallseg * ws)
|
||||||
|
|
||||||
void FDrawInfo::ClearFloodStencil(wallseg * ws)
|
void FDrawInfo::ClearFloodStencil(wallseg * ws)
|
||||||
{
|
{
|
||||||
int recursion = GLPortal::GetRecursion();
|
int recursion = GLRenderer->mPortalState.GetRecursion();
|
||||||
|
|
||||||
glStencilOp(GL_KEEP,GL_KEEP,GL_DECR);
|
glStencilOp(GL_KEEP,GL_KEEP,GL_DECR);
|
||||||
gl_RenderState.EnableTexture(false);
|
gl_RenderState.EnableTexture(false);
|
||||||
|
|
|
@ -112,11 +112,6 @@ struct FDrawInfo : public HWDrawInfo
|
||||||
void EndDrawScene(sector_t * viewsector);
|
void EndDrawScene(sector_t * viewsector);
|
||||||
void DrawEndScene2D(sector_t * viewsector);
|
void DrawEndScene2D(sector_t * viewsector);
|
||||||
|
|
||||||
// These should go into hwrenderer later.
|
|
||||||
void SetViewMatrix(const FRotator &angles, float vx, float vy, float vz, bool mirror, bool planemirror);
|
|
||||||
void SetupView(float vx, float vy, float vz, bool mirror, bool planemirror);
|
|
||||||
|
|
||||||
|
|
||||||
static FDrawInfo *StartDrawInfo(FRenderViewpoint &parentvp, HWViewpointUniforms *uniforms);
|
static FDrawInfo *StartDrawInfo(FRenderViewpoint &parentvp, HWViewpointUniforms *uniforms);
|
||||||
FDrawInfo *EndDrawInfo();
|
FDrawInfo *EndDrawInfo();
|
||||||
|
|
||||||
|
|
|
@ -58,42 +58,12 @@ EXTERN_CVAR(Bool, gl_portals)
|
||||||
EXTERN_CVAR(Bool, gl_noquery)
|
EXTERN_CVAR(Bool, gl_noquery)
|
||||||
EXTERN_CVAR(Int, r_mirror_recursions)
|
EXTERN_CVAR(Int, r_mirror_recursions)
|
||||||
|
|
||||||
TArray<GLPortal *> GLPortal::portals;
|
|
||||||
TArray<float> GLPortal::planestack;
|
|
||||||
int GLPortal::recursion;
|
|
||||||
int GLPortal::MirrorFlag;
|
|
||||||
int GLPortal::PlaneMirrorFlag;
|
|
||||||
int GLPortal::renderdepth;
|
|
||||||
int GLPortal::PlaneMirrorMode;
|
|
||||||
GLuint GLPortal::QueryObject;
|
|
||||||
|
|
||||||
bool GLPortal::inskybox;
|
|
||||||
|
|
||||||
UniqueList<GLSkyInfo> UniqueSkies;
|
|
||||||
UniqueList<GLHorizonInfo> UniqueHorizons;
|
|
||||||
UniqueList<secplane_t> UniquePlaneMirrors;
|
|
||||||
|
|
||||||
int skyboxrecursion = 0;
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
void GLPortal::ClearScreen(HWDrawInfo *di)
|
||||||
void GLPortal::BeginScene()
|
|
||||||
{
|
|
||||||
UniqueSkies.Clear();
|
|
||||||
UniqueHorizons.Clear();
|
|
||||||
UniquePlaneMirrors.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
void GLPortal::ClearScreen(FDrawInfo *di)
|
|
||||||
{
|
{
|
||||||
bool multi = !!glIsEnabled(GL_MULTISAMPLE);
|
bool multi = !!glIsEnabled(GL_MULTISAMPLE);
|
||||||
|
|
||||||
|
@ -142,17 +112,13 @@ void GLPortal::DrawPortalStencil()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Start
|
// Start
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo *outer_di, FDrawInfo **pDi)
|
bool GLPortal::Start(bool usestencil, bool doquery, HWDrawInfo *outer_di, HWDrawInfo **pDi)
|
||||||
{
|
{
|
||||||
*pDi = nullptr;
|
*pDi = nullptr;
|
||||||
rendered_portals++;
|
rendered_portals++;
|
||||||
|
@ -166,7 +132,7 @@ bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo *outer_di, FDrawIn
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create stencil
|
// Create stencil
|
||||||
glStencilFunc(GL_EQUAL,recursion,~0); // create stencil
|
glStencilFunc(GL_EQUAL, mState->recursion, ~0); // create stencil
|
||||||
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); // increment stencil of valid pixels
|
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); // increment stencil of valid pixels
|
||||||
{
|
{
|
||||||
ScopedColorMask colorMask(0, 0, 0, 0); // glColorMask(0,0,0,0); // don't write to the graphics buffer
|
ScopedColorMask colorMask(0, 0, 0, 0); // glColorMask(0,0,0,0); // don't write to the graphics buffer
|
||||||
|
@ -182,19 +148,15 @@ bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo *outer_di, FDrawIn
|
||||||
if (!NeedDepthBuffer()) doquery = false; // too much overhead and nothing to gain.
|
if (!NeedDepthBuffer()) doquery = false; // too much overhead and nothing to gain.
|
||||||
else if (gl_noquery) doquery = false;
|
else if (gl_noquery) doquery = false;
|
||||||
|
|
||||||
// If occlusion query is supported let's use it to avoid rendering portals that aren't visible
|
// Use occlusion query to avoid rendering portals that aren't visible
|
||||||
if (QueryObject)
|
glBeginQuery(GL_SAMPLES_PASSED, GLRenderer->PortalQueryObject);
|
||||||
{
|
|
||||||
glBeginQuery(GL_SAMPLES_PASSED, QueryObject);
|
|
||||||
}
|
|
||||||
else doquery = false; // some kind of error happened
|
|
||||||
|
|
||||||
DrawPortalStencil();
|
DrawPortalStencil();
|
||||||
|
|
||||||
glEndQuery(GL_SAMPLES_PASSED);
|
glEndQuery(GL_SAMPLES_PASSED);
|
||||||
|
|
||||||
// Clear Z-buffer
|
// Clear Z-buffer
|
||||||
glStencilFunc(GL_EQUAL, recursion + 1, ~0); // draw sky into stencil
|
glStencilFunc(GL_EQUAL, mState->recursion + 1, ~0); // draw sky into stencil
|
||||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // this stage doesn't modify the stencil
|
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // this stage doesn't modify the stencil
|
||||||
glDepthMask(true); // enable z-buffer again
|
glDepthMask(true); // enable z-buffer again
|
||||||
glDepthRange(1, 1);
|
glDepthRange(1, 1);
|
||||||
|
@ -210,17 +172,14 @@ bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo *outer_di, FDrawIn
|
||||||
|
|
||||||
GLuint sampleCount;
|
GLuint sampleCount;
|
||||||
|
|
||||||
if (QueryObject)
|
glGetQueryObjectuiv(GLRenderer->PortalQueryObject, GL_QUERY_RESULT, &sampleCount);
|
||||||
{
|
|
||||||
glGetQueryObjectuiv(QueryObject, GL_QUERY_RESULT, &sampleCount);
|
|
||||||
|
|
||||||
if (sampleCount == 0) // not visible
|
if (sampleCount == 0) // not visible
|
||||||
{
|
{
|
||||||
// restore default stencil op.
|
// restore default stencil op.
|
||||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||||
glStencilFunc(GL_EQUAL, recursion, ~0); // draw sky into stencil
|
glStencilFunc(GL_EQUAL, mState->recursion, ~0); // draw sky into stencil
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -232,7 +191,7 @@ bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo *outer_di, FDrawIn
|
||||||
|
|
||||||
glDepthMask(true);
|
glDepthMask(true);
|
||||||
DrawPortalStencil();
|
DrawPortalStencil();
|
||||||
glStencilFunc(GL_EQUAL, recursion + 1, ~0); // draw sky into stencil
|
glStencilFunc(GL_EQUAL, mState->recursion + 1, ~0); // draw sky into stencil
|
||||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // this stage doesn't modify the stencil
|
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // this stage doesn't modify the stencil
|
||||||
gl_RenderState.EnableTexture(true);
|
gl_RenderState.EnableTexture(true);
|
||||||
// glColorMask(1,1,1,1);
|
// glColorMask(1,1,1,1);
|
||||||
|
@ -241,7 +200,7 @@ bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo *outer_di, FDrawIn
|
||||||
glDepthMask(false); // don't write to Z-buffer!
|
glDepthMask(false); // don't write to Z-buffer!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
recursion++;
|
mState->recursion++;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -262,14 +221,13 @@ bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo *outer_di, FDrawIn
|
||||||
PrevPortal = GLRenderer->mCurrentPortal;
|
PrevPortal = GLRenderer->mCurrentPortal;
|
||||||
GLRenderer->mCurrentPortal = this;
|
GLRenderer->mCurrentPortal = this;
|
||||||
|
|
||||||
if (PrevPortal != nullptr) PrevPortal->PushState();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void GLPortal::ClearClipper(FDrawInfo *di)
|
inline void GLPortal::ClearClipper(HWDrawInfo *di)
|
||||||
{
|
{
|
||||||
auto outer_di = di->next;
|
auto outer_di = static_cast<FDrawInfo*>(di)->next;
|
||||||
DAngle angleOffset = deltaangle(outer_di->Viewpoint.Angles.Yaw, di->Viewpoint.Angles.Yaw);
|
DAngle angleOffset = deltaangle(outer_di->Viewpoint.Angles.Yaw, di->Viewpoint.Angles.Yaw);
|
||||||
|
|
||||||
di->mClipper->Clear();
|
di->mClipper->Clear();
|
||||||
|
@ -300,15 +258,14 @@ inline void GLPortal::ClearClipper(FDrawInfo *di)
|
||||||
// End
|
// End
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void GLPortal::End(FDrawInfo *di, bool usestencil)
|
void GLPortal::End(HWDrawInfo *di, bool usestencil)
|
||||||
{
|
{
|
||||||
bool needdepth = NeedDepthBuffer();
|
bool needdepth = NeedDepthBuffer();
|
||||||
|
|
||||||
Clocker c(PortalAll);
|
Clocker c(PortalAll);
|
||||||
if (PrevPortal != nullptr) PrevPortal->PopState();
|
|
||||||
GLRenderer->mCurrentPortal = PrevPortal;
|
GLRenderer->mCurrentPortal = PrevPortal;
|
||||||
|
|
||||||
di = di->EndDrawInfo();
|
di = static_cast<FDrawInfo*>(di)->EndDrawInfo();
|
||||||
di->ApplyVPUniforms();
|
di->ApplyVPUniforms();
|
||||||
if (usestencil)
|
if (usestencil)
|
||||||
{
|
{
|
||||||
|
@ -316,7 +273,6 @@ void GLPortal::End(FDrawInfo *di, bool usestencil)
|
||||||
|
|
||||||
// Restore the old view
|
// Restore the old view
|
||||||
if (vp.camera != nullptr) vp.camera->renderflags = (vp.camera->renderflags & ~RF_MAYBEINVISIBLE) | savedvisibility;
|
if (vp.camera != nullptr) vp.camera->renderflags = (vp.camera->renderflags & ~RF_MAYBEINVISIBLE) | savedvisibility;
|
||||||
di->SetupView(vp.Pos.X, vp.Pos.Y, vp.Pos.Z, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
|
|
||||||
|
|
||||||
{
|
{
|
||||||
ScopedColorMask colorMask(0, 0, 0, 0); // glColorMask(0, 0, 0, 0); // no graphics
|
ScopedColorMask colorMask(0, 0, 0, 0); // glColorMask(0, 0, 0, 0); // no graphics
|
||||||
|
@ -341,7 +297,7 @@ void GLPortal::End(FDrawInfo *di, bool usestencil)
|
||||||
glDepthFunc(GL_LEQUAL);
|
glDepthFunc(GL_LEQUAL);
|
||||||
glDepthRange(0, 1);
|
glDepthRange(0, 1);
|
||||||
glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
|
glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
|
||||||
glStencilFunc(GL_EQUAL, recursion, ~0); // draw sky into stencil
|
glStencilFunc(GL_EQUAL, mState->recursion, ~0); // draw sky into stencil
|
||||||
DrawPortalStencil();
|
DrawPortalStencil();
|
||||||
glDepthFunc(GL_LESS);
|
glDepthFunc(GL_LESS);
|
||||||
|
|
||||||
|
@ -349,11 +305,11 @@ void GLPortal::End(FDrawInfo *di, bool usestencil)
|
||||||
gl_RenderState.EnableTexture(true);
|
gl_RenderState.EnableTexture(true);
|
||||||
gl_RenderState.SetEffect(EFF_NONE);
|
gl_RenderState.SetEffect(EFF_NONE);
|
||||||
} // glColorMask(1, 1, 1, 1);
|
} // glColorMask(1, 1, 1, 1);
|
||||||
recursion--;
|
mState->recursion--;
|
||||||
|
|
||||||
// restore old stencil op.
|
// restore old stencil op.
|
||||||
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
|
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
|
||||||
glStencilFunc(GL_EQUAL,recursion,~0); // draw sky into stencil
|
glStencilFunc(GL_EQUAL, mState->recursion,~0); // draw sky into stencil
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -370,7 +326,7 @@ void GLPortal::End(FDrawInfo *di, bool usestencil)
|
||||||
|
|
||||||
// Restore the old view
|
// Restore the old view
|
||||||
if (vp.camera != nullptr) vp.camera->renderflags = (vp.camera->renderflags & ~RF_MAYBEINVISIBLE) | savedvisibility;
|
if (vp.camera != nullptr) vp.camera->renderflags = (vp.camera->renderflags & ~RF_MAYBEINVISIBLE) | savedvisibility;
|
||||||
di->SetupView(vp.Pos.X, vp.Pos.Y, vp.Pos.Z, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
|
di->SetupView(vp.Pos.X, vp.Pos.Y, vp.Pos.Z, !!(mState->MirrorFlag & 1), !!(mState->PlaneMirrorFlag & 1));
|
||||||
|
|
||||||
// This draws a valid z-buffer into the stencil's contents to ensure it
|
// This draws a valid z-buffer into the stencil's contents to ensure it
|
||||||
// doesn't get overwritten by the level's geometry.
|
// doesn't get overwritten by the level's geometry.
|
||||||
|
@ -394,141 +350,6 @@ void GLPortal::End(FDrawInfo *di, bool usestencil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// StartFrame
|
|
||||||
//
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void GLPortal::StartFrame()
|
|
||||||
{
|
|
||||||
GLPortal * p = nullptr;
|
|
||||||
portals.Push(p);
|
|
||||||
if (renderdepth == 0)
|
|
||||||
{
|
|
||||||
inskybox = false;
|
|
||||||
screen->instack[sector_t::floor] = screen->instack[sector_t::ceiling] = 0;
|
|
||||||
}
|
|
||||||
renderdepth++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// printing portal info
|
|
||||||
//
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static bool gl_portalinfo;
|
|
||||||
|
|
||||||
CCMD(gl_portalinfo)
|
|
||||||
{
|
|
||||||
gl_portalinfo = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static FString indent;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// EndFrame
|
|
||||||
//
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void GLPortal::EndFrame(FDrawInfo *outer_di)
|
|
||||||
{
|
|
||||||
GLPortal * p;
|
|
||||||
|
|
||||||
if (gl_portalinfo)
|
|
||||||
{
|
|
||||||
Printf("%s%d portals, depth = %d\n%s{\n", indent.GetChars(), portals.Size(), renderdepth, indent.GetChars());
|
|
||||||
indent += " ";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only use occlusion query if there are more than 2 portals.
|
|
||||||
// Otherwise there's too much overhead.
|
|
||||||
// (And don't forget to consider the separating nullptr pointers!)
|
|
||||||
bool usequery = portals.Size() > 2 + (unsigned)renderdepth;
|
|
||||||
|
|
||||||
while (portals.Pop(p) && p)
|
|
||||||
{
|
|
||||||
if (gl_portalinfo)
|
|
||||||
{
|
|
||||||
Printf("%sProcessing %s, depth = %d, query = %d\n", indent.GetChars(), p->GetName(), renderdepth, usequery);
|
|
||||||
}
|
|
||||||
if (p->lines.Size() > 0)
|
|
||||||
{
|
|
||||||
p->RenderPortal(true, usequery, outer_di);
|
|
||||||
}
|
|
||||||
delete p;
|
|
||||||
}
|
|
||||||
renderdepth--;
|
|
||||||
|
|
||||||
if (gl_portalinfo)
|
|
||||||
{
|
|
||||||
indent.Truncate(long(indent.Len()-2));
|
|
||||||
Printf("%s}\n", indent.GetChars());
|
|
||||||
if (portals.Size() == 0) gl_portalinfo = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Renders one sky portal without a stencil.
|
|
||||||
// In more complex scenes using a stencil for skies can severely stall
|
|
||||||
// the GPU and there's rarely more than one sky visible at a time.
|
|
||||||
//
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
bool GLPortal::RenderFirstSkyPortal(int recursion, FDrawInfo *outer_di)
|
|
||||||
{
|
|
||||||
GLPortal * p;
|
|
||||||
GLPortal * best = nullptr;
|
|
||||||
unsigned bestindex=0;
|
|
||||||
|
|
||||||
// Find the one with the highest amount of lines.
|
|
||||||
// Normally this is also the one that saves the largest amount
|
|
||||||
// of time by drawing it before the scene itself.
|
|
||||||
for(int i = portals.Size()-1; i >= 0 && portals[i] != nullptr; --i)
|
|
||||||
{
|
|
||||||
p=portals[i];
|
|
||||||
if (p->lines.Size() > 0 && p->IsSky())
|
|
||||||
{
|
|
||||||
// Cannot clear the depth buffer inside a portal recursion
|
|
||||||
if (recursion && p->NeedDepthBuffer()) continue;
|
|
||||||
|
|
||||||
if (!best || p->lines.Size()>best->lines.Size())
|
|
||||||
{
|
|
||||||
best=p;
|
|
||||||
bestindex=i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (best)
|
|
||||||
{
|
|
||||||
portals.Delete(bestindex);
|
|
||||||
best->RenderPortal(false, false, outer_di);
|
|
||||||
delete best;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// FindPortal
|
|
||||||
//
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
GLPortal * GLPortal::FindPortal(const void * src)
|
|
||||||
{
|
|
||||||
int i=portals.Size()-1;
|
|
||||||
|
|
||||||
while (i>=0 && portals[i] && portals[i]->GetSource()!=src) i--;
|
|
||||||
return i>=0? portals[i]:nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
|
@ -545,23 +366,23 @@ GLPortal * GLPortal::FindPortal(const void * src)
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void GLSkyboxPortal::DrawContents(FDrawInfo *di)
|
void GLSkyboxPortal::DrawContents(HWDrawInfo *di)
|
||||||
{
|
{
|
||||||
int old_pm = PlaneMirrorMode;
|
int old_pm = mState->PlaneMirrorMode;
|
||||||
|
|
||||||
if (skyboxrecursion >= 3)
|
if (mState->skyboxrecursion >= 3)
|
||||||
{
|
{
|
||||||
ClearScreen(di);
|
ClearScreen(di);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto &vp = di->Viewpoint;
|
auto &vp = di->Viewpoint;
|
||||||
|
|
||||||
skyboxrecursion++;
|
mState->skyboxrecursion++;
|
||||||
AActor *origin = portal->mSkybox;
|
AActor *origin = portal->mSkybox;
|
||||||
portal->mFlags |= PORTSF_INSKYBOX;
|
portal->mFlags |= PORTSF_INSKYBOX;
|
||||||
vp.extralight = 0;
|
vp.extralight = 0;
|
||||||
|
|
||||||
PlaneMirrorMode = 0;
|
mState->PlaneMirrorMode = 0;
|
||||||
|
|
||||||
bool oldclamp = gl_RenderState.SetDepthClamp(false);
|
bool oldclamp = gl_RenderState.SetDepthClamp(false);
|
||||||
vp.Pos = origin->InterpolatedPosition(vp.TicFrac);
|
vp.Pos = origin->InterpolatedPosition(vp.TicFrac);
|
||||||
|
@ -576,20 +397,20 @@ void GLSkyboxPortal::DrawContents(FDrawInfo *di)
|
||||||
|
|
||||||
vp.ViewActor = origin;
|
vp.ViewActor = origin;
|
||||||
|
|
||||||
inskybox = true;
|
mState->inskybox = true;
|
||||||
di->SetupView(vp.Pos.X, vp.Pos.Y, vp.Pos.Z, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
|
di->SetupView(vp.Pos.X, vp.Pos.Y, vp.Pos.Z, !!(mState->MirrorFlag & 1), !!(mState->PlaneMirrorFlag & 1));
|
||||||
di->SetViewArea();
|
di->SetViewArea();
|
||||||
ClearClipper(di);
|
ClearClipper(di);
|
||||||
|
|
||||||
di->UpdateCurrentMapSection();
|
di->UpdateCurrentMapSection();
|
||||||
|
|
||||||
di->DrawScene(DM_SKYPORTAL);
|
static_cast<FDrawInfo*>(di)->DrawScene(DM_PORTAL);
|
||||||
portal->mFlags &= ~PORTSF_INSKYBOX;
|
portal->mFlags &= ~PORTSF_INSKYBOX;
|
||||||
inskybox = false;
|
mState->inskybox = false;
|
||||||
gl_RenderState.SetDepthClamp(oldclamp);
|
gl_RenderState.SetDepthClamp(oldclamp);
|
||||||
skyboxrecursion--;
|
mState->skyboxrecursion--;
|
||||||
|
|
||||||
PlaneMirrorMode = old_pm;
|
mState->PlaneMirrorMode = old_pm;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -611,7 +432,7 @@ void GLSkyboxPortal::DrawContents(FDrawInfo *di)
|
||||||
|
|
||||||
GLSectorStackPortal *FSectorPortalGroup::GetRenderState()
|
GLSectorStackPortal *FSectorPortalGroup::GetRenderState()
|
||||||
{
|
{
|
||||||
if (glportal == nullptr) glportal = new GLSectorStackPortal(this);
|
if (glportal == nullptr) glportal = new GLSectorStackPortal(&GLRenderer->mPortalState, this);
|
||||||
return glportal;
|
return glportal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -631,7 +452,7 @@ GLSectorStackPortal::~GLSectorStackPortal()
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
static uint8_t SetCoverage(FDrawInfo *di, void *node)
|
static uint8_t SetCoverage(HWDrawInfo *di, void *node)
|
||||||
{
|
{
|
||||||
if (level.nodes.Size() == 0)
|
if (level.nodes.Size() == 0)
|
||||||
{
|
{
|
||||||
|
@ -651,7 +472,7 @@ static uint8_t SetCoverage(FDrawInfo *di, void *node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLSectorStackPortal::SetupCoverage(FDrawInfo *di)
|
void GLSectorStackPortal::SetupCoverage(HWDrawInfo *di)
|
||||||
{
|
{
|
||||||
for(unsigned i=0; i<subsectors.Size(); i++)
|
for(unsigned i=0; i<subsectors.Size(); i++)
|
||||||
{
|
{
|
||||||
|
@ -672,7 +493,7 @@ void GLSectorStackPortal::SetupCoverage(FDrawInfo *di)
|
||||||
// GLSectorStackPortal::DrawContents
|
// GLSectorStackPortal::DrawContents
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void GLSectorStackPortal::DrawContents(FDrawInfo *di)
|
void GLSectorStackPortal::DrawContents(HWDrawInfo *di)
|
||||||
{
|
{
|
||||||
FSectorPortalGroup *portal = origin;
|
FSectorPortalGroup *portal = origin;
|
||||||
auto &vp = di->Viewpoint;
|
auto &vp = di->Viewpoint;
|
||||||
|
@ -684,7 +505,7 @@ void GLSectorStackPortal::DrawContents(FDrawInfo *di)
|
||||||
// avoid recursions!
|
// avoid recursions!
|
||||||
if (origin->plane != -1) screen->instack[origin->plane]++;
|
if (origin->plane != -1) screen->instack[origin->plane]++;
|
||||||
|
|
||||||
di->SetupView(vp.Pos.X, vp.Pos.Y, vp.Pos.Z, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
|
di->SetupView(vp.Pos.X, vp.Pos.Y, vp.Pos.Z, !!(mState->MirrorFlag&1), !!(mState->PlaneMirrorFlag&1));
|
||||||
SetupCoverage(di);
|
SetupCoverage(di);
|
||||||
ClearClipper(di);
|
ClearClipper(di);
|
||||||
|
|
||||||
|
@ -697,7 +518,7 @@ void GLSectorStackPortal::DrawContents(FDrawInfo *di)
|
||||||
di->mClipper->SetBlocked(true);
|
di->mClipper->SetBlocked(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
di->DrawScene(DM_PORTAL);
|
static_cast<FDrawInfo*>(di)->DrawScene(DM_PORTAL);
|
||||||
|
|
||||||
if (origin->plane != -1) screen->instack[origin->plane]--;
|
if (origin->plane != -1) screen->instack[origin->plane]--;
|
||||||
}
|
}
|
||||||
|
@ -718,9 +539,9 @@ void GLSectorStackPortal::DrawContents(FDrawInfo *di)
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void GLPlaneMirrorPortal::DrawContents(FDrawInfo *di)
|
void GLPlaneMirrorPortal::DrawContents(HWDrawInfo *di)
|
||||||
{
|
{
|
||||||
if (renderdepth > r_mirror_recursions)
|
if (mState->renderdepth > r_mirror_recursions)
|
||||||
{
|
{
|
||||||
ClearScreen(di);
|
ClearScreen(di);
|
||||||
return;
|
return;
|
||||||
|
@ -729,7 +550,7 @@ void GLPlaneMirrorPortal::DrawContents(FDrawInfo *di)
|
||||||
std::swap(screen->instack[sector_t::floor], screen->instack[sector_t::ceiling]);
|
std::swap(screen->instack[sector_t::floor], screen->instack[sector_t::ceiling]);
|
||||||
|
|
||||||
auto &vp = di->Viewpoint;
|
auto &vp = di->Viewpoint;
|
||||||
int old_pm = PlaneMirrorMode;
|
int old_pm = mState->PlaneMirrorMode;
|
||||||
|
|
||||||
// the player is always visible in a mirror.
|
// the player is always visible in a mirror.
|
||||||
vp.showviewer = true;
|
vp.showviewer = true;
|
||||||
|
@ -737,18 +558,18 @@ void GLPlaneMirrorPortal::DrawContents(FDrawInfo *di)
|
||||||
double planez = origin->ZatPoint(vp.Pos);
|
double planez = origin->ZatPoint(vp.Pos);
|
||||||
vp.Pos.Z = 2 * planez - vp.Pos.Z;
|
vp.Pos.Z = 2 * planez - vp.Pos.Z;
|
||||||
vp.ViewActor = nullptr;
|
vp.ViewActor = nullptr;
|
||||||
PlaneMirrorMode = origin->fC() < 0 ? -1 : 1;
|
mState->PlaneMirrorMode = origin->fC() < 0 ? -1 : 1;
|
||||||
|
|
||||||
PlaneMirrorFlag++;
|
mState->PlaneMirrorFlag++;
|
||||||
di->SetClipHeight(planez, PlaneMirrorMode < 0 ? -1.f : 1.f);
|
di->SetClipHeight(planez, mState->PlaneMirrorMode < 0 ? -1.f : 1.f);
|
||||||
di->SetupView(vp.Pos.X, vp.Pos.Y, vp.Pos.Z, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
|
di->SetupView(vp.Pos.X, vp.Pos.Y, vp.Pos.Z, !!(mState->MirrorFlag & 1), !!(mState->PlaneMirrorFlag & 1));
|
||||||
ClearClipper(di);
|
ClearClipper(di);
|
||||||
|
|
||||||
di->UpdateCurrentMapSection();
|
di->UpdateCurrentMapSection();
|
||||||
|
|
||||||
di->DrawScene(DM_PORTAL);
|
static_cast<FDrawInfo*>(di)->DrawScene(DM_PORTAL);
|
||||||
PlaneMirrorFlag--;
|
mState->PlaneMirrorFlag--;
|
||||||
PlaneMirrorMode = old_pm;
|
mState->PlaneMirrorMode = old_pm;
|
||||||
std::swap(screen->instack[sector_t::floor], screen->instack[sector_t::ceiling]);
|
std::swap(screen->instack[sector_t::floor], screen->instack[sector_t::ceiling]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -803,9 +624,9 @@ int GLLinePortal::ClipPoint(const DVector2 &pos)
|
||||||
// R_EnterMirror
|
// R_EnterMirror
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void GLMirrorPortal::DrawContents(FDrawInfo *di)
|
void GLMirrorPortal::DrawContents(HWDrawInfo *di)
|
||||||
{
|
{
|
||||||
if (renderdepth>r_mirror_recursions)
|
if (mState->renderdepth>r_mirror_recursions)
|
||||||
{
|
{
|
||||||
ClearScreen(di);
|
ClearScreen(di);
|
||||||
return;
|
return;
|
||||||
|
@ -864,16 +685,16 @@ void GLMirrorPortal::DrawContents(FDrawInfo *di)
|
||||||
FVector2 v(-dx, dy);
|
FVector2 v(-dx, dy);
|
||||||
v.MakeUnit();
|
v.MakeUnit();
|
||||||
|
|
||||||
vp.Pos.X+= v[1] * renderdepth / 2;
|
vp.Pos.X+= v[1] * mState->renderdepth / 2;
|
||||||
vp.Pos.Y+= v[0] * renderdepth / 2;
|
vp.Pos.Y+= v[0] * mState->renderdepth / 2;
|
||||||
}
|
}
|
||||||
vp.Angles.Yaw = linedef->Delta().Angle() * 2. - StartAngle;
|
vp.Angles.Yaw = linedef->Delta().Angle() * 2. - StartAngle;
|
||||||
|
|
||||||
vp.ViewActor = nullptr;
|
vp.ViewActor = nullptr;
|
||||||
|
|
||||||
MirrorFlag++;
|
mState->MirrorFlag++;
|
||||||
di->SetClipLine(linedef);
|
di->SetClipLine(linedef);
|
||||||
di->SetupView(vp.Pos.X, vp.Pos.Y, vp.Pos.Z, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
|
di->SetupView(vp.Pos.X, vp.Pos.Y, vp.Pos.Z, !!(mState->MirrorFlag&1), !!(mState->PlaneMirrorFlag&1));
|
||||||
|
|
||||||
di->mClipper->Clear();
|
di->mClipper->Clear();
|
||||||
|
|
||||||
|
@ -882,9 +703,9 @@ void GLMirrorPortal::DrawContents(FDrawInfo *di)
|
||||||
|
|
||||||
di->mClipper->SafeAddClipRange(linedef->v1, linedef->v2);
|
di->mClipper->SafeAddClipRange(linedef->v1, linedef->v2);
|
||||||
|
|
||||||
di->DrawScene(DM_PORTAL);
|
static_cast<FDrawInfo*>(di)->DrawScene(DM_PORTAL);
|
||||||
|
|
||||||
MirrorFlag--;
|
mState->MirrorFlag--;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -902,10 +723,10 @@ void GLMirrorPortal::DrawContents(FDrawInfo *di)
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void GLLineToLinePortal::DrawContents(FDrawInfo *di)
|
void GLLineToLinePortal::DrawContents(HWDrawInfo *di)
|
||||||
{
|
{
|
||||||
// TODO: Handle recursion more intelligently
|
// TODO: Handle recursion more intelligently
|
||||||
if (renderdepth>r_mirror_recursions)
|
if (mState->renderdepth>r_mirror_recursions)
|
||||||
{
|
{
|
||||||
ClearScreen(di);
|
ClearScreen(di);
|
||||||
return;
|
return;
|
||||||
|
@ -948,13 +769,13 @@ void GLLineToLinePortal::DrawContents(FDrawInfo *di)
|
||||||
|
|
||||||
vp.ViewActor = nullptr;
|
vp.ViewActor = nullptr;
|
||||||
di->SetClipLine(glport->lines[0]->mDestination);
|
di->SetClipLine(glport->lines[0]->mDestination);
|
||||||
di->SetupView(vp.Pos.X, vp.Pos.Y, vp.Pos.Z, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
|
di->SetupView(vp.Pos.X, vp.Pos.Y, vp.Pos.Z, !!(mState->MirrorFlag&1), !!(mState->PlaneMirrorFlag&1));
|
||||||
|
|
||||||
ClearClipper(di);
|
ClearClipper(di);
|
||||||
di->DrawScene(DM_PORTAL);
|
static_cast<FDrawInfo*>(di)->DrawScene(DM_PORTAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLLineToLinePortal::RenderAttached(FDrawInfo *di)
|
void GLLineToLinePortal::RenderAttached(HWDrawInfo *di)
|
||||||
{
|
{
|
||||||
di->ProcessActorsInPortal(glport, di->in_area);
|
di->ProcessActorsInPortal(glport, di->in_area);
|
||||||
}
|
}
|
||||||
|
@ -981,8 +802,8 @@ void GLLineToLinePortal::RenderAttached(FDrawInfo *di)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
GLHorizonPortal::GLHorizonPortal(GLHorizonInfo * pt, FRenderViewpoint &vp, bool local)
|
GLHorizonPortal::GLHorizonPortal(FPortalSceneState *s, GLHorizonInfo * pt, FRenderViewpoint &vp, bool local)
|
||||||
: GLPortal(local)
|
: GLPortal(s, local)
|
||||||
{
|
{
|
||||||
origin = pt;
|
origin = pt;
|
||||||
|
|
||||||
|
@ -1045,8 +866,9 @@ GLHorizonPortal::GLHorizonPortal(GLHorizonInfo * pt, FRenderViewpoint &vp, bool
|
||||||
// GLHorizonPortal::DrawContents
|
// GLHorizonPortal::DrawContents
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void GLHorizonPortal::DrawContents(FDrawInfo *di)
|
void GLHorizonPortal::DrawContents(HWDrawInfo *hwdi)
|
||||||
{
|
{
|
||||||
|
auto di = static_cast<FDrawInfo *>(hwdi);
|
||||||
Clocker c(PortalAll);
|
Clocker c(PortalAll);
|
||||||
|
|
||||||
FMaterial * gltexture;
|
FMaterial * gltexture;
|
||||||
|
@ -1117,7 +939,7 @@ void GLHorizonPortal::DrawContents(FDrawInfo *di)
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void GLEEHorizonPortal::DrawContents(FDrawInfo *di)
|
void GLEEHorizonPortal::DrawContents(HWDrawInfo *di)
|
||||||
{
|
{
|
||||||
auto &vp = di->Viewpoint;
|
auto &vp = di->Viewpoint;
|
||||||
sector_t *sector = portal->mOrigin;
|
sector_t *sector = portal->mOrigin;
|
||||||
|
@ -1126,7 +948,7 @@ void GLEEHorizonPortal::DrawContents(FDrawInfo *di)
|
||||||
{
|
{
|
||||||
GLSkyInfo skyinfo;
|
GLSkyInfo skyinfo;
|
||||||
skyinfo.init(sector->sky, 0);
|
skyinfo.init(sector->sky, 0);
|
||||||
GLSkyPortal sky(&skyinfo, true);
|
GLSkyPortal sky(mState, &skyinfo, true);
|
||||||
sky.DrawContents(di);
|
sky.DrawContents(di);
|
||||||
}
|
}
|
||||||
if (sector->GetTexture(sector_t::ceiling) != skyflatnum)
|
if (sector->GetTexture(sector_t::ceiling) != skyflatnum)
|
||||||
|
@ -1140,7 +962,7 @@ void GLEEHorizonPortal::DrawContents(FDrawInfo *di)
|
||||||
{
|
{
|
||||||
horz.plane.Texheight = vp.Pos.Z + fabs(horz.plane.Texheight);
|
horz.plane.Texheight = vp.Pos.Z + fabs(horz.plane.Texheight);
|
||||||
}
|
}
|
||||||
GLHorizonPortal ceil(&horz, di->Viewpoint, true);
|
GLHorizonPortal ceil(mState, &horz, di->Viewpoint, true);
|
||||||
ceil.DrawContents(di);
|
ceil.DrawContents(di);
|
||||||
}
|
}
|
||||||
if (sector->GetTexture(sector_t::floor) != skyflatnum)
|
if (sector->GetTexture(sector_t::floor) != skyflatnum)
|
||||||
|
@ -1154,26 +976,11 @@ void GLEEHorizonPortal::DrawContents(FDrawInfo *di)
|
||||||
{
|
{
|
||||||
horz.plane.Texheight = vp.Pos.Z - fabs(horz.plane.Texheight);
|
horz.plane.Texheight = vp.Pos.Z - fabs(horz.plane.Texheight);
|
||||||
}
|
}
|
||||||
GLHorizonPortal floor(&horz, di->Viewpoint, true);
|
GLHorizonPortal floor(mState, &horz, di->Viewpoint, true);
|
||||||
floor.DrawContents(di);
|
floor.DrawContents(di);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLPortal::Initialize()
|
|
||||||
{
|
|
||||||
assert(0 == QueryObject);
|
|
||||||
glGenQueries(1, &QueryObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLPortal::Shutdown()
|
|
||||||
{
|
|
||||||
if (0 != QueryObject)
|
|
||||||
{
|
|
||||||
glDeleteQueries(1, &QueryObject);
|
|
||||||
QueryObject = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *GLSkyPortal::GetName() { return "Sky"; }
|
const char *GLSkyPortal::GetName() { return "Sky"; }
|
||||||
const char *GLSkyboxPortal::GetName() { return "Skybox"; }
|
const char *GLSkyboxPortal::GetName() { return "Skybox"; }
|
||||||
const char *GLSectorStackPortal::GetName() { return "Sectorstack"; }
|
const char *GLSectorStackPortal::GetName() { return "Sectorstack"; }
|
||||||
|
|
|
@ -44,92 +44,27 @@
|
||||||
#include "hwrenderer/scene/hw_drawstructs.h"
|
#include "hwrenderer/scene/hw_drawstructs.h"
|
||||||
#include "hwrenderer/scene/hw_portal.h"
|
#include "hwrenderer/scene/hw_portal.h"
|
||||||
|
|
||||||
extern UniqueList<GLSkyInfo> UniqueSkies;
|
|
||||||
extern UniqueList<GLHorizonInfo> UniqueHorizons;
|
|
||||||
extern UniqueList<secplane_t> UniquePlaneMirrors;
|
|
||||||
struct GLEEHorizonPortal;
|
struct GLEEHorizonPortal;
|
||||||
|
|
||||||
class GLPortal : public IPortal
|
class GLPortal : public IPortal
|
||||||
{
|
{
|
||||||
static TArray<GLPortal *> portals;
|
|
||||||
static int recursion;
|
|
||||||
static unsigned int QueryObject;
|
|
||||||
protected:
|
|
||||||
static TArray<float> planestack;
|
|
||||||
static int MirrorFlag;
|
|
||||||
static int PlaneMirrorFlag;
|
|
||||||
static int renderdepth;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static int PlaneMirrorMode;
|
|
||||||
static int inupperstack;
|
|
||||||
static bool inskybox;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void DrawPortalStencil();
|
void DrawPortalStencil();
|
||||||
|
|
||||||
AActor * savedviewactor;
|
|
||||||
ActorRenderFlags savedvisibility;
|
ActorRenderFlags savedvisibility;
|
||||||
GLPortal *PrevPortal;
|
GLPortal *PrevPortal;
|
||||||
TArray<unsigned int> mPrimIndices;
|
TArray<unsigned int> mPrimIndices;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TArray<GLWall> lines;
|
|
||||||
int level;
|
int level;
|
||||||
|
|
||||||
GLPortal(bool local = false) { if (!local) portals.Push(this); }
|
GLPortal(FPortalSceneState *state, bool local = false) : IPortal(state, local) { }
|
||||||
virtual ~GLPortal() { }
|
|
||||||
|
|
||||||
bool Start(bool usestencil, bool doquery, FDrawInfo *outer_di, FDrawInfo **pDi);
|
bool Start(bool usestencil, bool doquery, HWDrawInfo *outer_di, HWDrawInfo **pDi) override;
|
||||||
void End(FDrawInfo *di, bool usestencil);
|
void End(HWDrawInfo *di, bool usestencil) override;
|
||||||
virtual void DrawContents(FDrawInfo *di)=0;
|
void ClearClipper(HWDrawInfo *di);
|
||||||
virtual void * GetSource() const =0; // GetSource MUST be implemented!
|
void ClearScreen(HWDrawInfo *di);
|
||||||
void ClearClipper(FDrawInfo *di);
|
|
||||||
virtual bool IsSky() { return false; }
|
|
||||||
virtual bool NeedCap() { return true; }
|
|
||||||
virtual bool NeedDepthBuffer() { return true; }
|
|
||||||
void ClearScreen(FDrawInfo *di);
|
|
||||||
virtual const char *GetName() = 0;
|
|
||||||
virtual void PushState() {}
|
|
||||||
virtual void PopState() {}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void RenderPortal(bool usestencil, bool doquery, FDrawInfo *outer_di)
|
|
||||||
{
|
|
||||||
// Start may perform an occlusion query. If that returns 0 there
|
|
||||||
// is no need to draw the stencil's contents and there's also no
|
|
||||||
// need to restore the affected area becasue there is none!
|
|
||||||
FDrawInfo *di;
|
|
||||||
if (Start(usestencil, doquery, outer_di, &di))
|
|
||||||
{
|
|
||||||
DrawContents(di);
|
|
||||||
End(di, usestencil);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddLine(GLWall * l)
|
|
||||||
{
|
|
||||||
lines.Push(*l);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int GetRecursion()
|
|
||||||
{
|
|
||||||
return recursion;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isMirrored() { return !!((MirrorFlag ^ PlaneMirrorFlag) & 1); }
|
|
||||||
|
|
||||||
virtual void RenderAttached(FDrawInfo *di) {}
|
|
||||||
|
|
||||||
static void BeginScene();
|
|
||||||
static void StartFrame();
|
|
||||||
static bool RenderFirstSkyPortal(int recursion, FDrawInfo *outer_di);
|
|
||||||
static void EndFrame(FDrawInfo *outer_di);
|
|
||||||
static GLPortal * FindPortal(const void * src);
|
|
||||||
|
|
||||||
static void Initialize();
|
|
||||||
static void Shutdown();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GLLinePortal : public GLPortal
|
struct GLLinePortal : public GLPortal
|
||||||
|
@ -140,14 +75,14 @@ struct GLLinePortal : public GLPortal
|
||||||
|
|
||||||
angle_t angv1, angv2; // for quick comparisons with a line or subsector
|
angle_t angv1, angv2; // for quick comparisons with a line or subsector
|
||||||
|
|
||||||
GLLinePortal(line_t *line)
|
GLLinePortal(FPortalSceneState *state, line_t *line) : GLPortal(state)
|
||||||
{
|
{
|
||||||
v1 = line->v1;
|
v1 = line->v1;
|
||||||
v2 = line->v2;
|
v2 = line->v2;
|
||||||
CalcDelta();
|
CalcDelta();
|
||||||
}
|
}
|
||||||
|
|
||||||
GLLinePortal(FLinePortalSpan *line)
|
GLLinePortal(FPortalSceneState *state, FLinePortalSpan *line) : GLPortal(state)
|
||||||
{
|
{
|
||||||
if (line->lines[0]->mType != PORTT_LINKED || line->v1 == nullptr)
|
if (line->lines[0]->mType != PORTT_LINKED || line->v1 == nullptr)
|
||||||
{
|
{
|
||||||
|
@ -189,14 +124,14 @@ struct GLMirrorPortal : public GLLinePortal
|
||||||
line_t * linedef;
|
line_t * linedef;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void DrawContents(FDrawInfo *di);
|
virtual void DrawContents(HWDrawInfo *di);
|
||||||
virtual void * GetSource() const { return linedef; }
|
virtual void * GetSource() const { return linedef; }
|
||||||
virtual const char *GetName();
|
virtual const char *GetName();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
GLMirrorPortal(line_t * line)
|
GLMirrorPortal(FPortalSceneState *state, line_t * line)
|
||||||
: GLLinePortal(line)
|
: GLLinePortal(state, line)
|
||||||
{
|
{
|
||||||
linedef=line;
|
linedef=line;
|
||||||
}
|
}
|
||||||
|
@ -207,16 +142,16 @@ struct GLLineToLinePortal : public GLLinePortal
|
||||||
{
|
{
|
||||||
FLinePortalSpan *glport;
|
FLinePortalSpan *glport;
|
||||||
protected:
|
protected:
|
||||||
virtual void DrawContents(FDrawInfo *di);
|
virtual void DrawContents(HWDrawInfo *di);
|
||||||
virtual void * GetSource() const { return glport; }
|
virtual void * GetSource() const { return glport; }
|
||||||
virtual const char *GetName();
|
virtual const char *GetName();
|
||||||
virtual line_t *ClipLine() { return line(); }
|
virtual line_t *ClipLine() { return line(); }
|
||||||
virtual void RenderAttached(FDrawInfo *di);
|
virtual void RenderAttached(HWDrawInfo *di);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
GLLineToLinePortal(FLinePortalSpan *ll)
|
GLLineToLinePortal(FPortalSceneState *state, FLinePortalSpan *ll)
|
||||||
: GLLinePortal(ll)
|
: GLLinePortal(state, ll)
|
||||||
{
|
{
|
||||||
glport = ll;
|
glport = ll;
|
||||||
}
|
}
|
||||||
|
@ -228,7 +163,7 @@ struct GLSkyboxPortal : public GLPortal
|
||||||
FSectorPortal * portal;
|
FSectorPortal * portal;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void DrawContents(FDrawInfo *di);
|
virtual void DrawContents(HWDrawInfo *di);
|
||||||
virtual void * GetSource() const { return portal; }
|
virtual void * GetSource() const { return portal; }
|
||||||
virtual bool IsSky() { return true; }
|
virtual bool IsSky() { return true; }
|
||||||
virtual const char *GetName();
|
virtual const char *GetName();
|
||||||
|
@ -236,7 +171,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
GLSkyboxPortal(FSectorPortal * pt)
|
GLSkyboxPortal(FPortalSceneState *state, FSectorPortal * pt) : GLPortal(state)
|
||||||
{
|
{
|
||||||
portal=pt;
|
portal=pt;
|
||||||
}
|
}
|
||||||
|
@ -250,7 +185,7 @@ struct GLSkyPortal : public GLPortal
|
||||||
friend struct GLEEHorizonPortal;
|
friend struct GLEEHorizonPortal;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void DrawContents(FDrawInfo *di);
|
virtual void DrawContents(HWDrawInfo *di);
|
||||||
virtual void * GetSource() const { return origin; }
|
virtual void * GetSource() const { return origin; }
|
||||||
virtual bool IsSky() { return true; }
|
virtual bool IsSky() { return true; }
|
||||||
virtual bool NeedDepthBuffer() { return false; }
|
virtual bool NeedDepthBuffer() { return false; }
|
||||||
|
@ -259,8 +194,8 @@ protected:
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
GLSkyPortal(GLSkyInfo * pt, bool local = false)
|
GLSkyPortal(FPortalSceneState *state, GLSkyInfo * pt, bool local = false)
|
||||||
: GLPortal(local)
|
: GLPortal(state, local)
|
||||||
{
|
{
|
||||||
origin=pt;
|
origin=pt;
|
||||||
}
|
}
|
||||||
|
@ -274,7 +209,7 @@ struct GLSectorStackPortal : public GLPortal
|
||||||
TArray<subsector_t *> subsectors;
|
TArray<subsector_t *> subsectors;
|
||||||
protected:
|
protected:
|
||||||
virtual ~GLSectorStackPortal();
|
virtual ~GLSectorStackPortal();
|
||||||
virtual void DrawContents(FDrawInfo *di);
|
virtual void DrawContents(HWDrawInfo *di);
|
||||||
virtual void * GetSource() const { return origin; }
|
virtual void * GetSource() const { return origin; }
|
||||||
virtual bool IsSky() { return true; } // although this isn't a real sky it can be handled as one.
|
virtual bool IsSky() { return true; } // although this isn't a real sky it can be handled as one.
|
||||||
virtual const char *GetName();
|
virtual const char *GetName();
|
||||||
|
@ -282,11 +217,11 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
GLSectorStackPortal(FSectorPortalGroup *pt)
|
GLSectorStackPortal(FPortalSceneState *state, FSectorPortalGroup *pt) : GLPortal(state)
|
||||||
{
|
{
|
||||||
origin=pt;
|
origin=pt;
|
||||||
}
|
}
|
||||||
void SetupCoverage(FDrawInfo *di);
|
void SetupCoverage(HWDrawInfo *di);
|
||||||
void AddSubsector(subsector_t *sub)
|
void AddSubsector(subsector_t *sub)
|
||||||
{
|
{
|
||||||
subsectors.Push(sub);
|
subsectors.Push(sub);
|
||||||
|
@ -297,14 +232,14 @@ public:
|
||||||
struct GLPlaneMirrorPortal : public GLPortal
|
struct GLPlaneMirrorPortal : public GLPortal
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
virtual void DrawContents(FDrawInfo *di);
|
virtual void DrawContents(HWDrawInfo *di);
|
||||||
virtual void * GetSource() const { return origin; }
|
virtual void * GetSource() const { return origin; }
|
||||||
virtual const char *GetName();
|
virtual const char *GetName();
|
||||||
secplane_t * origin;
|
secplane_t * origin;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
GLPlaneMirrorPortal(secplane_t * pt)
|
GLPlaneMirrorPortal(FPortalSceneState *state, secplane_t * pt) : GLPortal(state)
|
||||||
{
|
{
|
||||||
origin=pt;
|
origin=pt;
|
||||||
}
|
}
|
||||||
|
@ -320,7 +255,7 @@ struct GLHorizonPortal : public GLPortal
|
||||||
friend struct GLEEHorizonPortal;
|
friend struct GLEEHorizonPortal;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void DrawContents(FDrawInfo *di);
|
virtual void DrawContents(HWDrawInfo *di);
|
||||||
virtual void * GetSource() const { return origin; }
|
virtual void * GetSource() const { return origin; }
|
||||||
virtual bool NeedDepthBuffer() { return false; }
|
virtual bool NeedDepthBuffer() { return false; }
|
||||||
virtual bool NeedCap() { return false; }
|
virtual bool NeedCap() { return false; }
|
||||||
|
@ -328,7 +263,7 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
GLHorizonPortal(GLHorizonInfo * pt, FRenderViewpoint &vp, bool local = false);
|
GLHorizonPortal(FPortalSceneState *state, GLHorizonInfo * pt, FRenderViewpoint &vp, bool local = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GLEEHorizonPortal : public GLPortal
|
struct GLEEHorizonPortal : public GLPortal
|
||||||
|
@ -336,7 +271,7 @@ struct GLEEHorizonPortal : public GLPortal
|
||||||
FSectorPortal * portal;
|
FSectorPortal * portal;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void DrawContents(FDrawInfo *di);
|
virtual void DrawContents(HWDrawInfo *di);
|
||||||
virtual void * GetSource() const { return portal; }
|
virtual void * GetSource() const { return portal; }
|
||||||
virtual bool NeedDepthBuffer() { return false; }
|
virtual bool NeedDepthBuffer() { return false; }
|
||||||
virtual bool NeedCap() { return false; }
|
virtual bool NeedCap() { return false; }
|
||||||
|
@ -344,7 +279,7 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
GLEEHorizonPortal(FSectorPortal *pt)
|
GLEEHorizonPortal(FPortalSceneState *state, FSectorPortal *pt) : GLPortal(state)
|
||||||
{
|
{
|
||||||
portal=pt;
|
portal=pt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
#include "gl/renderer/gl_renderbuffers.h"
|
#include "gl/renderer/gl_renderbuffers.h"
|
||||||
#include "gl/data/gl_vertexbuffer.h"
|
#include "gl/data/gl_vertexbuffer.h"
|
||||||
#include "hwrenderer/scene/hw_clipper.h"
|
#include "hwrenderer/scene/hw_clipper.h"
|
||||||
|
#include "hwrenderer/scene/hw_portal.h"
|
||||||
#include "gl/scene/gl_drawinfo.h"
|
#include "gl/scene/gl_drawinfo.h"
|
||||||
#include "gl/scene/gl_portal.h"
|
#include "gl/scene/gl_portal.h"
|
||||||
#include "gl/stereo3d/gl_stereo3d.h"
|
#include "gl/stereo3d/gl_stereo3d.h"
|
||||||
|
@ -91,41 +92,6 @@ void FDrawInfo::ApplyVPUniforms()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Setup the modelview matrix
|
|
||||||
//
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void FDrawInfo::SetViewMatrix(const FRotator &angles, float vx, float vy, float vz, bool mirror, bool planemirror)
|
|
||||||
{
|
|
||||||
float mult = mirror? -1:1;
|
|
||||||
float planemult = planemirror? -level.info->pixelstretch : level.info->pixelstretch;
|
|
||||||
|
|
||||||
VPUniforms.mViewMatrix.loadIdentity();
|
|
||||||
VPUniforms.mViewMatrix.rotate(angles.Roll.Degrees, 0.0f, 0.0f, 1.0f);
|
|
||||||
VPUniforms.mViewMatrix.rotate(angles.Pitch.Degrees, 1.0f, 0.0f, 0.0f);
|
|
||||||
VPUniforms.mViewMatrix.rotate(angles.Yaw.Degrees, 0.0f, mult, 0.0f);
|
|
||||||
VPUniforms.mViewMatrix.translate(vx * mult, -vz * planemult , -vy);
|
|
||||||
VPUniforms.mViewMatrix.scale(-mult, planemult, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// SetupView
|
|
||||||
// Setup the view rotation matrix for the given viewpoint
|
|
||||||
//
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void FDrawInfo::SetupView(float vx, float vy, float vz, bool mirror, bool planemirror)
|
|
||||||
{
|
|
||||||
auto &vp = Viewpoint;
|
|
||||||
vp.SetViewAngle(r_viewwindow);
|
|
||||||
SetViewMatrix(vp.HWAngles, vx, vy, vz, mirror, planemirror);
|
|
||||||
SetCameraPos(vp.Pos);
|
|
||||||
ApplyVPUniforms();
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// CreateScene
|
// CreateScene
|
||||||
|
@ -141,7 +107,7 @@ void FDrawInfo::CreateScene()
|
||||||
mClipper->SafeAddClipRangeRealAngles(vp.Angles.Yaw.BAMs() + a1, vp.Angles.Yaw.BAMs() - a1);
|
mClipper->SafeAddClipRangeRealAngles(vp.Angles.Yaw.BAMs() + a1, vp.Angles.Yaw.BAMs() - a1);
|
||||||
|
|
||||||
// reset the portal manager
|
// reset the portal manager
|
||||||
GLPortal::StartFrame();
|
GLRenderer->mPortalState.StartFrame();
|
||||||
PO_LinkToSubsectors();
|
PO_LinkToSubsectors();
|
||||||
|
|
||||||
ProcessAll.Clock();
|
ProcessAll.Clock();
|
||||||
|
@ -195,7 +161,7 @@ void FDrawInfo::RenderScene(int recursion)
|
||||||
RenderAll.Clock();
|
RenderAll.Clock();
|
||||||
|
|
||||||
glDepthMask(true);
|
glDepthMask(true);
|
||||||
if (!gl_no_skyclear) GLPortal::RenderFirstSkyPortal(recursion, this);
|
if (!gl_no_skyclear) GLRenderer->mPortalState.RenderFirstSkyPortal(recursion, this);
|
||||||
|
|
||||||
gl_RenderState.EnableFog(true);
|
gl_RenderState.EnableFog(true);
|
||||||
gl_RenderState.BlendFunc(GL_ONE,GL_ZERO);
|
gl_RenderState.BlendFunc(GL_ONE,GL_ZERO);
|
||||||
|
@ -377,7 +343,7 @@ void FDrawInfo::DrawScene(int drawmode)
|
||||||
// Handle all portals after rendering the opaque objects but before
|
// Handle all portals after rendering the opaque objects but before
|
||||||
// doing all translucent stuff
|
// doing all translucent stuff
|
||||||
recursion++;
|
recursion++;
|
||||||
GLPortal::EndFrame(this);
|
GLRenderer->mPortalState.EndFrame(this);
|
||||||
recursion--;
|
recursion--;
|
||||||
RenderTranslucent();
|
RenderTranslucent();
|
||||||
}
|
}
|
||||||
|
@ -444,7 +410,7 @@ void FDrawInfo::DrawEndScene2D(sector_t * viewsector)
|
||||||
void FDrawInfo::ProcessScene(bool toscreen)
|
void FDrawInfo::ProcessScene(bool toscreen)
|
||||||
{
|
{
|
||||||
iter_dlightf = iter_dlight = draw_dlight = draw_dlightf = 0;
|
iter_dlightf = iter_dlight = draw_dlight = draw_dlightf = 0;
|
||||||
GLPortal::BeginScene();
|
GLRenderer->mPortalState.BeginScene();
|
||||||
|
|
||||||
int mapsection = R_PointInSubsector(Viewpoint.Pos)->mapsection;
|
int mapsection = R_PointInSubsector(Viewpoint.Pos)->mapsection;
|
||||||
CurrentMapSections.Set(mapsection);
|
CurrentMapSections.Set(mapsection);
|
||||||
|
|
|
@ -210,7 +210,7 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void GLSkyPortal::DrawContents(FDrawInfo *di)
|
void GLSkyPortal::DrawContents(HWDrawInfo *di)
|
||||||
{
|
{
|
||||||
bool drawBoth = false;
|
bool drawBoth = false;
|
||||||
auto &vp = di->Viewpoint;
|
auto &vp = di->Viewpoint;
|
||||||
|
@ -230,7 +230,7 @@ void GLSkyPortal::DrawContents(FDrawInfo *di)
|
||||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
bool oldClamp = gl_RenderState.SetDepthClamp(true);
|
bool oldClamp = gl_RenderState.SetDepthClamp(true);
|
||||||
|
|
||||||
di->SetupView(0, 0, 0, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
|
di->SetupView(0, 0, 0, !!(mState->MirrorFlag & 1), !!(mState->PlaneMirrorFlag & 1));
|
||||||
|
|
||||||
gl_RenderState.SetVertexBuffer(GLRenderer->mSkyVBO);
|
gl_RenderState.SetVertexBuffer(GLRenderer->mSkyVBO);
|
||||||
if (origin->texture[0] && origin->texture[0]->tex->bSkybox)
|
if (origin->texture[0] && origin->texture[0]->tex->bSkybox)
|
||||||
|
|
|
@ -337,7 +337,8 @@ void FDrawInfo::AddMirrorSurface(GLWall *w)
|
||||||
|
|
||||||
void FDrawInfo::AddPortal(GLWall *wall, int ptype)
|
void FDrawInfo::AddPortal(GLWall *wall, int ptype)
|
||||||
{
|
{
|
||||||
GLPortal * portal;
|
auto &pstate = GLRenderer->mPortalState;
|
||||||
|
IPortal * portal;
|
||||||
|
|
||||||
wall->MakeVertices(this, false);
|
wall->MakeVertices(this, false);
|
||||||
switch (ptype)
|
switch (ptype)
|
||||||
|
@ -345,19 +346,19 @@ void FDrawInfo::AddPortal(GLWall *wall, int ptype)
|
||||||
// portals don't go into the draw list.
|
// portals don't go into the draw list.
|
||||||
// Instead they are added to the portal manager
|
// Instead they are added to the portal manager
|
||||||
case PORTALTYPE_HORIZON:
|
case PORTALTYPE_HORIZON:
|
||||||
wall->horizon = UniqueHorizons.Get(wall->horizon);
|
wall->horizon = pstate.UniqueHorizons.Get(wall->horizon);
|
||||||
portal = GLPortal::FindPortal(wall->horizon);
|
portal = pstate.FindPortal(wall->horizon);
|
||||||
if (!portal) portal = new GLHorizonPortal(wall->horizon, Viewpoint);
|
if (!portal) portal = new GLHorizonPortal(&pstate, wall->horizon, Viewpoint);
|
||||||
portal->AddLine(wall);
|
portal->AddLine(wall);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PORTALTYPE_SKYBOX:
|
case PORTALTYPE_SKYBOX:
|
||||||
portal = GLPortal::FindPortal(wall->secportal);
|
portal = pstate.FindPortal(wall->secportal);
|
||||||
if (!portal)
|
if (!portal)
|
||||||
{
|
{
|
||||||
// either a regular skybox or an Eternity-style horizon
|
// either a regular skybox or an Eternity-style horizon
|
||||||
if (wall->secportal->mType != PORTS_SKYVIEWPOINT) portal = new GLEEHorizonPortal(wall->secportal);
|
if (wall->secportal->mType != PORTS_SKYVIEWPOINT) portal = new GLEEHorizonPortal(&pstate, wall->secportal);
|
||||||
else portal = new GLSkyboxPortal(wall->secportal);
|
else portal = new GLSkyboxPortal(&pstate, wall->secportal);
|
||||||
}
|
}
|
||||||
portal->AddLine(wall);
|
portal->AddLine(wall);
|
||||||
break;
|
break;
|
||||||
|
@ -368,19 +369,19 @@ void FDrawInfo::AddPortal(GLWall *wall, int ptype)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PORTALTYPE_PLANEMIRROR:
|
case PORTALTYPE_PLANEMIRROR:
|
||||||
if (GLPortal::PlaneMirrorMode * wall->planemirror->fC() <= 0)
|
if (pstate.PlaneMirrorMode * wall->planemirror->fC() <= 0)
|
||||||
{
|
{
|
||||||
//@sync-portal
|
//@sync-portal
|
||||||
wall->planemirror = UniquePlaneMirrors.Get(wall->planemirror);
|
wall->planemirror = pstate.UniquePlaneMirrors.Get(wall->planemirror);
|
||||||
portal = GLPortal::FindPortal(wall->planemirror);
|
portal = pstate.FindPortal(wall->planemirror);
|
||||||
if (!portal) portal = new GLPlaneMirrorPortal(wall->planemirror);
|
if (!portal) portal = new GLPlaneMirrorPortal(&pstate, wall->planemirror);
|
||||||
portal->AddLine(wall);
|
portal->AddLine(wall);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PORTALTYPE_MIRROR:
|
case PORTALTYPE_MIRROR:
|
||||||
portal = GLPortal::FindPortal(wall->seg->linedef);
|
portal = pstate.FindPortal(wall->seg->linedef);
|
||||||
if (!portal) portal = new GLMirrorPortal(wall->seg->linedef);
|
if (!portal) portal = new GLMirrorPortal(&pstate, wall->seg->linedef);
|
||||||
portal->AddLine(wall);
|
portal->AddLine(wall);
|
||||||
if (gl_mirror_envmap)
|
if (gl_mirror_envmap)
|
||||||
{
|
{
|
||||||
|
@ -390,7 +391,7 @@ void FDrawInfo::AddPortal(GLWall *wall, int ptype)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PORTALTYPE_LINETOLINE:
|
case PORTALTYPE_LINETOLINE:
|
||||||
portal = GLPortal::FindPortal(wall->lineportal);
|
portal = pstate.FindPortal(wall->lineportal);
|
||||||
if (!portal)
|
if (!portal)
|
||||||
{
|
{
|
||||||
line_t *otherside = wall->lineportal->lines[0]->mDestination;
|
line_t *otherside = wall->lineportal->lines[0]->mDestination;
|
||||||
|
@ -398,15 +399,15 @@ void FDrawInfo::AddPortal(GLWall *wall, int ptype)
|
||||||
{
|
{
|
||||||
ProcessActorsInPortal(otherside->getPortal()->mGroup, in_area);
|
ProcessActorsInPortal(otherside->getPortal()->mGroup, in_area);
|
||||||
}
|
}
|
||||||
portal = new GLLineToLinePortal(wall->lineportal);
|
portal = new GLLineToLinePortal(&pstate, wall->lineportal);
|
||||||
}
|
}
|
||||||
portal->AddLine(wall);
|
portal->AddLine(wall);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PORTALTYPE_SKY:
|
case PORTALTYPE_SKY:
|
||||||
wall->sky = UniqueSkies.Get(wall->sky);
|
wall->sky = pstate.UniqueSkies.Get(wall->sky);
|
||||||
portal = GLPortal::FindPortal(wall->sky);
|
portal = pstate.FindPortal(wall->sky);
|
||||||
if (!portal) portal = new GLSkyPortal(wall->sky);
|
if (!portal) portal = new GLSkyPortal(&pstate, wall->sky);
|
||||||
portal->AddLine(wall);
|
portal->AddLine(wall);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,6 +214,42 @@ angle_t HWDrawInfo::FrustumAngle()
|
||||||
return a1;
|
return a1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Setup the modelview matrix
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void HWDrawInfo::SetViewMatrix(const FRotator &angles, float vx, float vy, float vz, bool mirror, bool planemirror)
|
||||||
|
{
|
||||||
|
float mult = mirror ? -1 : 1;
|
||||||
|
float planemult = planemirror ? -level.info->pixelstretch : level.info->pixelstretch;
|
||||||
|
|
||||||
|
VPUniforms.mViewMatrix.loadIdentity();
|
||||||
|
VPUniforms.mViewMatrix.rotate(angles.Roll.Degrees, 0.0f, 0.0f, 1.0f);
|
||||||
|
VPUniforms.mViewMatrix.rotate(angles.Pitch.Degrees, 1.0f, 0.0f, 0.0f);
|
||||||
|
VPUniforms.mViewMatrix.rotate(angles.Yaw.Degrees, 0.0f, mult, 0.0f);
|
||||||
|
VPUniforms.mViewMatrix.translate(vx * mult, -vz * planemult, -vy);
|
||||||
|
VPUniforms.mViewMatrix.scale(-mult, planemult, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// SetupView
|
||||||
|
// Setup the view rotation matrix for the given viewpoint
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void HWDrawInfo::SetupView(float vx, float vy, float vz, bool mirror, bool planemirror)
|
||||||
|
{
|
||||||
|
auto &vp = Viewpoint;
|
||||||
|
vp.SetViewAngle(r_viewwindow);
|
||||||
|
SetViewMatrix(vp.HWAngles, vx, vy, vz, mirror, planemirror);
|
||||||
|
SetCameraPos(vp.Pos);
|
||||||
|
ApplyVPUniforms();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
|
@ -217,6 +217,8 @@ public:
|
||||||
void PrepareTargeterSprites();
|
void PrepareTargeterSprites();
|
||||||
|
|
||||||
void UpdateCurrentMapSection();
|
void UpdateCurrentMapSection();
|
||||||
|
void SetViewMatrix(const FRotator &angles, float vx, float vy, float vz, bool mirror, bool planemirror);
|
||||||
|
void SetupView(float vx, float vy, float vz, bool mirror, bool planemirror);
|
||||||
angle_t FrustumAngle();
|
angle_t FrustumAngle();
|
||||||
|
|
||||||
virtual void DrawWall(GLWall *wall, int pass) = 0;
|
virtual void DrawWall(GLWall *wall, int pass) = 0;
|
||||||
|
|
157
src/hwrenderer/scene/hw_portal.cpp
Normal file
157
src/hwrenderer/scene/hw_portal.cpp
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright(C) 2004-2018 Christoph Oelckers
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||||
|
//
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
/*
|
||||||
|
** hw_portal.cpp
|
||||||
|
** portal maintenance classes for skyboxes, horizons etc. (API independent parts)
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "c_dispatch.h"
|
||||||
|
#include "hw_portal.h"
|
||||||
|
|
||||||
|
IPortal * FPortalSceneState::FindPortal(const void * src)
|
||||||
|
{
|
||||||
|
int i = portals.Size() - 1;
|
||||||
|
|
||||||
|
while (i >= 0 && portals[i] && portals[i]->GetSource() != src) i--;
|
||||||
|
return i >= 0 ? portals[i] : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// StartFrame
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void FPortalSceneState::StartFrame()
|
||||||
|
{
|
||||||
|
IPortal * p = nullptr;
|
||||||
|
portals.Push(p);
|
||||||
|
if (renderdepth == 0)
|
||||||
|
{
|
||||||
|
inskybox = false;
|
||||||
|
screen->instack[sector_t::floor] = screen->instack[sector_t::ceiling] = 0;
|
||||||
|
}
|
||||||
|
renderdepth++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// printing portal info
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static bool gl_portalinfo;
|
||||||
|
|
||||||
|
CCMD(gl_portalinfo)
|
||||||
|
{
|
||||||
|
gl_portalinfo = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FString indent;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// EndFrame
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void FPortalSceneState::EndFrame(HWDrawInfo *outer_di)
|
||||||
|
{
|
||||||
|
IPortal * p;
|
||||||
|
|
||||||
|
if (gl_portalinfo)
|
||||||
|
{
|
||||||
|
Printf("%s%d portals, depth = %d\n%s{\n", indent.GetChars(), portals.Size(), renderdepth, indent.GetChars());
|
||||||
|
indent += " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only use occlusion query if there are more than 2 portals.
|
||||||
|
// Otherwise there's too much overhead.
|
||||||
|
// (And don't forget to consider the separating null pointers!)
|
||||||
|
bool usequery = portals.Size() > 2 + (unsigned)renderdepth;
|
||||||
|
|
||||||
|
while (portals.Pop(p) && p)
|
||||||
|
{
|
||||||
|
if (gl_portalinfo)
|
||||||
|
{
|
||||||
|
Printf("%sProcessing %s, depth = %d, query = %d\n", indent.GetChars(), p->GetName(), renderdepth, usequery);
|
||||||
|
}
|
||||||
|
if (p->lines.Size() > 0)
|
||||||
|
{
|
||||||
|
p->RenderPortal(true, usequery, outer_di);
|
||||||
|
}
|
||||||
|
delete p;
|
||||||
|
}
|
||||||
|
renderdepth--;
|
||||||
|
|
||||||
|
if (gl_portalinfo)
|
||||||
|
{
|
||||||
|
indent.Truncate(long(indent.Len()-2));
|
||||||
|
Printf("%s}\n", indent.GetChars());
|
||||||
|
if (portals.Size() == 0) gl_portalinfo = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Renders one sky portal without a stencil.
|
||||||
|
// In more complex scenes using a stencil for skies can severely stall
|
||||||
|
// the GPU and there's rarely more than one sky visible at a time.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool FPortalSceneState::RenderFirstSkyPortal(int recursion, HWDrawInfo *outer_di)
|
||||||
|
{
|
||||||
|
IPortal * p;
|
||||||
|
IPortal * best = nullptr;
|
||||||
|
unsigned bestindex=0;
|
||||||
|
|
||||||
|
// Find the one with the highest amount of lines.
|
||||||
|
// Normally this is also the one that saves the largest amount
|
||||||
|
// of time by drawing it before the scene itself.
|
||||||
|
for(int i = portals.Size()-1; i >= 0 && portals[i] != nullptr; --i)
|
||||||
|
{
|
||||||
|
p=portals[i];
|
||||||
|
if (p->lines.Size() > 0 && p->IsSky())
|
||||||
|
{
|
||||||
|
// Cannot clear the depth buffer inside a portal recursion
|
||||||
|
if (recursion && p->NeedDepthBuffer()) continue;
|
||||||
|
|
||||||
|
if (!best || p->lines.Size()>best->lines.Size())
|
||||||
|
{
|
||||||
|
best=p;
|
||||||
|
bestindex=i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (best)
|
||||||
|
{
|
||||||
|
portals.Delete(bestindex);
|
||||||
|
best->RenderPortal(false, false, outer_di);
|
||||||
|
delete best;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "hw_drawinfo.h"
|
#include "hw_drawinfo.h"
|
||||||
|
#include "hw_drawstructs.h"
|
||||||
#include "hwrenderer/textures/hw_material.h"
|
#include "hwrenderer/textures/hw_material.h"
|
||||||
|
|
||||||
struct GLSkyInfo
|
struct GLSkyInfo
|
||||||
|
@ -33,12 +34,96 @@ struct GLHorizonInfo
|
||||||
PalEntry specialcolor;
|
PalEntry specialcolor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FPortalSceneState;
|
||||||
|
|
||||||
class IPortal
|
class IPortal
|
||||||
{
|
{
|
||||||
|
friend struct FPortalSceneState;
|
||||||
|
protected:
|
||||||
|
FPortalSceneState * mState;
|
||||||
|
TArray<GLWall> lines;
|
||||||
public:
|
public:
|
||||||
|
IPortal(FPortalSceneState *s, bool local);
|
||||||
virtual ~IPortal() {}
|
virtual ~IPortal() {}
|
||||||
virtual int ClipSeg(seg_t *seg, const DVector3 &viewpos) { return PClip_Inside; }
|
virtual int ClipSeg(seg_t *seg, const DVector3 &viewpos) { return PClip_Inside; }
|
||||||
virtual int ClipSubsector(subsector_t *sub) { return PClip_Inside; }
|
virtual int ClipSubsector(subsector_t *sub) { return PClip_Inside; }
|
||||||
virtual int ClipPoint(const DVector2 &pos) { return PClip_Inside; }
|
virtual int ClipPoint(const DVector2 &pos) { return PClip_Inside; }
|
||||||
virtual line_t *ClipLine() { return nullptr; }
|
virtual line_t *ClipLine() { return nullptr; }
|
||||||
|
virtual void * GetSource() const = 0; // GetSource MUST be implemented!
|
||||||
|
virtual const char *GetName() = 0;
|
||||||
|
virtual bool IsSky() { return false; }
|
||||||
|
virtual bool NeedCap() { return true; }
|
||||||
|
virtual bool NeedDepthBuffer() { return true; }
|
||||||
|
virtual void DrawContents(HWDrawInfo *di) = 0;
|
||||||
|
virtual void RenderAttached(HWDrawInfo *di) {}
|
||||||
|
virtual bool Start(bool usestencil, bool doquery, HWDrawInfo *outer_di, HWDrawInfo **pDi) = 0;
|
||||||
|
virtual void End(HWDrawInfo *di, bool usestencil) = 0;
|
||||||
|
|
||||||
|
void AddLine(GLWall * l)
|
||||||
|
{
|
||||||
|
lines.Push(*l);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderPortal(bool usestencil, bool doquery, HWDrawInfo *outer_di)
|
||||||
|
{
|
||||||
|
// Start may perform an occlusion query. If that returns 0 there
|
||||||
|
// is no need to draw the stencil's contents and there's also no
|
||||||
|
// need to restore the affected area becasue there is none!
|
||||||
|
HWDrawInfo *di;
|
||||||
|
if (Start(usestencil, doquery, outer_di, &di))
|
||||||
|
{
|
||||||
|
DrawContents(di);
|
||||||
|
End(di, usestencil);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FPortalSceneState
|
||||||
|
{
|
||||||
|
TArray<IPortal *> portals;
|
||||||
|
int recursion = 0;
|
||||||
|
|
||||||
|
int MirrorFlag = 0;
|
||||||
|
int PlaneMirrorFlag = 0;
|
||||||
|
int renderdepth = 0;
|
||||||
|
|
||||||
|
int PlaneMirrorMode = 0;
|
||||||
|
bool inskybox = 0;
|
||||||
|
|
||||||
|
UniqueList<GLSkyInfo> UniqueSkies;
|
||||||
|
UniqueList<GLHorizonInfo> UniqueHorizons;
|
||||||
|
UniqueList<secplane_t> UniquePlaneMirrors;
|
||||||
|
|
||||||
|
int skyboxrecursion = 0;
|
||||||
|
|
||||||
|
void BeginScene()
|
||||||
|
{
|
||||||
|
UniqueSkies.Clear();
|
||||||
|
UniqueHorizons.Clear();
|
||||||
|
UniquePlaneMirrors.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetRecursion() const
|
||||||
|
{
|
||||||
|
return recursion;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isMirrored() const
|
||||||
|
{
|
||||||
|
return !!((MirrorFlag ^ PlaneMirrorFlag) & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
IPortal * FindPortal(const void * src);
|
||||||
|
void StartFrame();
|
||||||
|
bool RenderFirstSkyPortal(int recursion, HWDrawInfo *outer_di);
|
||||||
|
void EndFrame(HWDrawInfo *outer_di);
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
inline IPortal::IPortal(FPortalSceneState *s, bool local) : mState(s)
|
||||||
|
{
|
||||||
|
if (!local) s->portals.Push(this);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue