- preparations for using clip planes on line portals.

This commit is contained in:
Christoph Oelckers 2016-04-29 01:48:06 +02:00
parent e3fad118d2
commit 21283b18f4
12 changed files with 133 additions and 70 deletions

View file

@ -84,6 +84,7 @@
FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb) FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
{ {
framebuffer = fb; framebuffer = fb;
mClipPortal = NULL;
mCurrentPortal = NULL; mCurrentPortal = NULL;
mMirrorCount = 0; mMirrorCount = 0;
mPlaneMirrorCount = 0; mPlaneMirrorCount = 0;

View file

@ -59,6 +59,7 @@ class FGLRenderer
public: public:
OpenGLFrameBuffer *framebuffer; OpenGLFrameBuffer *framebuffer;
GLPortal *mClipPortal;
GLPortal *mCurrentPortal; GLPortal *mCurrentPortal;
int mMirrorCount; int mMirrorCount;
int mPlaneMirrorCount; int mPlaneMirrorCount;

View file

@ -69,7 +69,7 @@ TArray<VSMatrix> gl_MatrixStack;
void FRenderState::Reset() void FRenderState::Reset()
{ {
mTextureEnabled = true; mTextureEnabled = true;
mSplitEnabled = mBrightmapEnabled = mFogEnabled = mGlowEnabled = false; mClipLineEnabled = mSplitEnabled = mBrightmapEnabled = mFogEnabled = mGlowEnabled = false;
mColorMask[0] = mColorMask[1] = mColorMask[2] = mColorMask[3] = true; mColorMask[0] = mColorMask[1] = mColorMask[2] = mColorMask[3] = true;
currentColorMask[0] = currentColorMask[1] = currentColorMask[2] = currentColorMask[3] = true; currentColorMask[0] = currentColorMask[1] = currentColorMask[2] = currentColorMask[3] = true;
mFogColor.d = -1; mFogColor.d = -1;
@ -171,10 +171,22 @@ bool FRenderState::ApplyShader()
activeShader->muSplitBottomPlane.Set(mSplitBottomPlane.vec); activeShader->muSplitBottomPlane.Set(mSplitBottomPlane.vec);
activeShader->currentsplitstate = 1; activeShader->currentsplitstate = 1;
} }
else else if (activeShader->currentsplitstate)
{ {
activeShader->muSplitTopPlane.Set(nulvec); activeShader->muSplitTopPlane.Set(nulvec);
activeShader->muSplitBottomPlane.Set(nulvec); activeShader->muSplitBottomPlane.Set(nulvec);
activeShader->currentsplitstate = 0;
}
if (mClipLineEnabled)
{
activeShader->muClipLine.Set(mClipLine.vec);
activeShader->currentcliplinestate = 1;
}
else if (activeShader->currentcliplinestate)
{
activeShader->muClipLine.Set(-10000000.0, 0, 0, 0);
activeShader->currentcliplinestate = 0;
} }
if (mColormapState != activeShader->currentfixedcolormap) if (mColormapState != activeShader->currentfixedcolormap)

View file

@ -47,6 +47,7 @@ class FRenderState
bool mFogEnabled; bool mFogEnabled;
bool mGlowEnabled; bool mGlowEnabled;
bool mSplitEnabled; bool mSplitEnabled;
bool mClipLineEnabled;
bool mBrightmapEnabled; bool mBrightmapEnabled;
bool mColorMask[4]; bool mColorMask[4];
bool currentColorMask[4]; bool currentColorMask[4];
@ -73,6 +74,7 @@ class FRenderState
FStateVec4 mGlowTop, mGlowBottom; FStateVec4 mGlowTop, mGlowBottom;
FStateVec4 mGlowTopPlane, mGlowBottomPlane; FStateVec4 mGlowTopPlane, mGlowBottomPlane;
FStateVec4 mSplitTopPlane, mSplitBottomPlane; FStateVec4 mSplitTopPlane, mSplitBottomPlane;
FStateVec4 mClipLine;
PalEntry mFogColor; PalEntry mFogColor;
PalEntry mObjectColor; PalEntry mObjectColor;
FStateVec4 mDynColor; FStateVec4 mDynColor;
@ -145,6 +147,16 @@ public:
return mClipHeightDirection; return mClipHeightDirection;
} }
FStateVec4 &GetClipLine()
{
return mClipLine;
}
bool GetClipLineState()
{
return mClipLineEnabled;
}
void SetClipHeight(float height, float direction); void SetClipHeight(float height, float direction);
void SetColor(float r, float g, float b, float a = 1.f, int desat = 0) void SetColor(float r, float g, float b, float a = 1.f, int desat = 0)
@ -241,6 +253,27 @@ public:
} }
} }
void SetClipLine(line_t *line)
{
mClipLine.Set(line->v1->fX(), line->v1->fY(), line->Delta().X, line->Delta().Y);
}
void EnableClipLine(bool on)
{
if (gl.glslversion >= 1.3f)
{
mClipLineEnabled = on;
if (on)
{
glEnable(GL_CLIP_DISTANCE0);
}
else
{
glDisable(GL_CLIP_DISTANCE0);
}
}
}
void SetLightIndex(int n) void SetLightIndex(int n)
{ {
mLightIndex = n; mLightIndex = n;

View file

@ -111,7 +111,7 @@ static void AddLine (seg_t *seg, bool portalclip)
if (portalclip) if (portalclip)
{ {
int clipres = GLRenderer->mCurrentPortal->ClipSeg(seg); int clipres = GLRenderer->mClipPortal->ClipSeg(seg);
if (clipres == GLPortal::PClip_InFront) return; if (clipres == GLPortal::PClip_InFront) return;
} }
@ -218,7 +218,7 @@ static void PolySubsector(subsector_t * sub)
{ {
if (line->linedef) if (line->linedef)
{ {
AddLine (line, GLRenderer->mCurrentPortal != NULL); AddLine (line, GLRenderer->mClipPortal != NULL);
} }
line++; line++;
} }
@ -313,11 +313,11 @@ static inline void AddLines(subsector_t * sub, sector_t * sector)
{ {
if (seg->linedef == NULL) if (seg->linedef == NULL)
{ {
if (!(sub->flags & SSECF_DRAWN)) AddLine (seg, GLRenderer->mCurrentPortal != NULL); if (!(sub->flags & SSECF_DRAWN)) AddLine (seg, GLRenderer->mClipPortal != NULL);
} }
else if (!(seg->sidedef->Flags & WALLF_POLYOBJ)) else if (!(seg->sidedef->Flags & WALLF_POLYOBJ))
{ {
AddLine (seg, GLRenderer->mCurrentPortal != NULL); AddLine (seg, GLRenderer->mClipPortal != NULL);
} }
seg++; seg++;
} }
@ -447,12 +447,12 @@ static void DoSubsector(subsector_t * sub)
fakesector=gl_FakeFlat(sector, &fake, false); fakesector=gl_FakeFlat(sector, &fake, false);
if (GLRenderer->mCurrentPortal) if (GLRenderer->mClipPortal)
{ {
int clipres = GLRenderer->mCurrentPortal->ClipSubsector(sub); int clipres = GLRenderer->mClipPortal->ClipSubsector(sub);
if (clipres == GLPortal::PClip_InFront) if (clipres == GLPortal::PClip_InFront)
{ {
line_t *line = GLRenderer->mCurrentPortal->ClipLine(); line_t *line = GLRenderer->mClipPortal->ClipLine();
// The subsector is out of range, but we still have to check lines that lie directly on the boundary and may expose their upper or lower parts. // The subsector is out of range, but we still have to check lines that lie directly on the boundary and may expose their upper or lower parts.
if (line) AddSpecialPortalLines(sub, fakesector, line); if (line) AddSpecialPortalLines(sub, fakesector, line);
return; return;

View file

@ -300,9 +300,6 @@ bool GLPortal::Start(bool usestencil, bool doquery)
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
} }
} }
planestack.Push(gl_RenderState.GetClipHeight());
planestack.Push(gl_RenderState.GetClipHeightDirection());
gl_RenderState.SetClipHeight(0., 0.);
// save viewpoint // save viewpoint
savedViewPos = ViewPos; savedViewPos = ViewPos;
@ -313,8 +310,12 @@ bool GLPortal::Start(bool usestencil, bool doquery)
savedviewpath[0] = ViewPath[0]; savedviewpath[0] = ViewPath[0];
savedviewpath[1] = ViewPath[1]; savedviewpath[1] = ViewPath[1];
NextPortal = GLRenderer->mCurrentPortal; PrevPortal = GLRenderer->mCurrentPortal;
GLRenderer->mCurrentPortal = NULL; // Portals which need this have to set it themselves PrevClipPortal = GLRenderer->mClipPortal;
GLRenderer->mClipPortal = NULL; // Portals which need this have to set it themselves
GLRenderer->mCurrentPortal = this;
if (PrevPortal != NULL) PrevPortal->PushState();
PortalAll.Unclock(); PortalAll.Unclock();
return true; return true;
} }
@ -359,12 +360,9 @@ void GLPortal::End(bool usestencil)
bool needdepth = NeedDepthBuffer(); bool needdepth = NeedDepthBuffer();
PortalAll.Clock(); PortalAll.Clock();
GLRenderer->mCurrentPortal = NextPortal; if (PrevPortal != NULL) PrevPortal->PopState();
GLRenderer->mCurrentPortal = PrevPortal;
float f, d; GLRenderer->mClipPortal = PrevClipPortal;
planestack.Pop(d);
planestack.Pop(f);
gl_RenderState.SetClipHeight(f, d);
if (usestencil) if (usestencil)
{ {
@ -806,14 +804,59 @@ void GLPlaneMirrorPortal::DrawContents()
PlaneMirrorMode=old_pm; PlaneMirrorMode=old_pm;
} }
void GLPlaneMirrorPortal::PushState()
{
planestack.Push(gl_RenderState.GetClipHeight());
planestack.Push(gl_RenderState.GetClipHeightDirection());
gl_RenderState.SetClipHeight(0.f, 0.f);
}
void GLPlaneMirrorPortal::PopState()
{
float d, f;
planestack.Pop(d);
planestack.Pop(f);
gl_RenderState.SetClipHeight(f, d);
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// //
// GLPlaneMirrorPortal::DrawContents // Common code for line to line and mirror portals
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
int GLLinePortal::ClipSeg(seg_t *seg)
{
line_t *linedef = seg->linedef;
if (!linedef)
{
return PClip_Inside; // should be handled properly.
}
return P_ClipLineToPortal(linedef, line(), ViewPos) ? PClip_InFront : PClip_Inside;
}
int GLLinePortal::ClipSubsector(subsector_t *sub)
{
// this seg is completely behind the mirror!
for(unsigned int i=0;i<sub->numlines;i++)
{
if (P_PointOnLineSidePrecise(sub->firstline[i].v1->fPos(), line()) == 0) return PClip_Inside;
}
return PClip_InFront;
}
int GLLinePortal::ClipPoint(const DVector2 &pos)
{
if (P_PointOnLineSidePrecise(pos, line()))
{
return PClip_InFront;
}
return PClip_Inside;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// //
@ -837,7 +880,7 @@ void GLMirrorPortal::DrawContents()
return; return;
} }
GLRenderer->mCurrentPortal = this; GLRenderer->mClipPortal = this;
DAngle StartAngle = ViewAngle; DAngle StartAngle = ViewAngle;
DVector3 StartPos = ViewPos; DVector3 StartPos = ViewPos;
@ -910,37 +953,6 @@ void GLMirrorPortal::DrawContents()
MirrorFlag--; MirrorFlag--;
} }
int GLLinePortal::ClipSeg(seg_t *seg)
{
line_t *linedef = seg->linedef;
if (!linedef)
{
return PClip_Inside; // should be handled properly.
}
return P_ClipLineToPortal(linedef, line(), ViewPos) ? PClip_InFront : PClip_Inside;
}
int GLLinePortal::ClipSubsector(subsector_t *sub)
{
// this seg is completely behind the mirror!
for(unsigned int i=0;i<sub->numlines;i++)
{
if (P_PointOnLineSidePrecise(sub->firstline[i].v1->fPos(), line()) == 0) return PClip_Inside;
}
return PClip_InFront;
}
int GLLinePortal::ClipPoint(const DVector2 &pos)
{
if (P_PointOnLineSidePrecise(pos, line()))
{
return PClip_InFront;
}
return PClip_Inside;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// //
@ -965,7 +977,7 @@ void GLLineToLinePortal::DrawContents()
return; return;
} }
GLRenderer->mCurrentPortal = this; GLRenderer->mClipPortal = this;
line_t *origin = glport->reference->mOrigin; line_t *origin = glport->reference->mOrigin;
P_TranslatePortalXY(origin, ViewPos.X, ViewPos.Y); P_TranslatePortalXY(origin, ViewPos.X, ViewPos.Y);

View file

@ -107,7 +107,8 @@ private:
area_t savedviewarea; area_t savedviewarea;
bool savedshowviewer; bool savedshowviewer;
DVector3 savedviewpath[2]; DVector3 savedviewpath[2];
GLPortal *NextPortal; GLPortal *PrevPortal;
GLPortal *PrevClipPortal;
TArray<BYTE> savedmapsection; TArray<BYTE> savedmapsection;
TArray<unsigned int> mPrimIndices; TArray<unsigned int> mPrimIndices;
@ -130,6 +131,8 @@ protected:
virtual const char *GetName() = 0; virtual const char *GetName() = 0;
void SaveMapSection(); void SaveMapSection();
void RestoreMapSection(); void RestoreMapSection();
virtual void PushState() {}
virtual void PopState() {}
public: public:
@ -341,6 +344,8 @@ protected:
virtual void DrawContents(); virtual void DrawContents();
virtual void * GetSource() const { return origin; } virtual void * GetSource() const { return origin; }
virtual const char *GetName(); virtual const char *GetName();
virtual void PushState();
virtual void PopState();
secplane_t * origin; secplane_t * origin;
public: public:

View file

@ -503,7 +503,7 @@ void FGLRenderer::DrawScene(bool toscreen)
static int recursion=0; static int recursion=0;
CreateScene(); CreateScene();
GLRenderer->mCurrentPortal = NULL; // this must be reset before any portal recursion takes place. GLRenderer->mClipPortal = NULL; // this must be reset before any portal recursion takes place.
// Up to this point in the main draw call no rendering is performed so we can wait // Up to this point in the main draw call no rendering is performed so we can wait
// with swapping the render buffer until now. // with swapping the render buffer until now.

View file

@ -581,9 +581,9 @@ void GLSprite::Process(AActor* thing, sector_t * sector, bool thruportal)
thing->flags7 |= MF7_FLYCHEAT; // do this only once for the very first frame, but not if it gets into range again. thing->flags7 |= MF7_FLYCHEAT; // do this only once for the very first frame, but not if it gets into range again.
} }
if (GLRenderer->mCurrentPortal) if (GLRenderer->mClipPortal)
{ {
int clipres = GLRenderer->mCurrentPortal->ClipPoint(thingpos); int clipres = GLRenderer->mClipPortal->ClipPoint(thingpos);
if (clipres == GLPortal::PClip_InFront) return; if (clipres == GLPortal::PClip_InFront) return;
} }
@ -894,9 +894,9 @@ void GLSprite::Process(AActor* thing, sector_t * sector, bool thruportal)
void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int shade, int fakeside) void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int shade, int fakeside)
{ {
if (GLRenderer->mCurrentPortal) if (GLRenderer->mClipPortal)
{ {
int clipres = GLRenderer->mCurrentPortal->ClipPoint(particle->Pos); int clipres = GLRenderer->mClipPortal->ClipPoint(particle->Pos);
if (clipres == GLPortal::PClip_InFront) return; if (clipres == GLPortal::PClip_InFront) return;
} }

View file

@ -278,6 +278,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
muGlowTopPlane.Init(hShader, "uGlowTopPlane"); muGlowTopPlane.Init(hShader, "uGlowTopPlane");
muSplitBottomPlane.Init(hShader, "uSplitBottomPlane"); muSplitBottomPlane.Init(hShader, "uSplitBottomPlane");
muSplitTopPlane.Init(hShader, "uSplitTopPlane"); muSplitTopPlane.Init(hShader, "uSplitTopPlane");
muClipLine.Init(hShader, "uClipLine");
muFixedColormap.Init(hShader, "uFixedColormap"); muFixedColormap.Init(hShader, "uFixedColormap");
muInterpolationFactor.Init(hShader, "uInterpolationFactor"); muInterpolationFactor.Init(hShader, "uInterpolationFactor");
muClipHeight.Init(hShader, "uClipHeight"); muClipHeight.Init(hShader, "uClipHeight");

View file

@ -220,6 +220,7 @@ class FShader
FUniform4f muGlowTopPlane; FUniform4f muGlowTopPlane;
FUniform4f muSplitBottomPlane; FUniform4f muSplitBottomPlane;
FUniform4f muSplitTopPlane; FUniform4f muSplitTopPlane;
FUniform4f muClipLine;
FBufferedUniform1f muInterpolationFactor; FBufferedUniform1f muInterpolationFactor;
FBufferedUniform1f muClipHeight; FBufferedUniform1f muClipHeight;
FBufferedUniform1f muClipHeightDirection; FBufferedUniform1f muClipHeightDirection;
@ -234,22 +235,18 @@ class FShader
public: public:
int fakevb_index; int fakevb_index;
private: private:
int currentglowstate; int currentglowstate = 0;
int currentsplitstate; int currentsplitstate = 0;
int currentfixedcolormap; int currentcliplinestate = 0;
bool currentTextureMatrixState; int currentfixedcolormap = 0;
bool currentModelMatrixState; bool currentTextureMatrixState = true;// by setting the matrix state to 'true' it is guaranteed to be set the first time the render state gets applied.
bool currentModelMatrixState = true;
public: public:
FShader(const char *name) FShader(const char *name)
: mName(name) : mName(name)
{ {
hShader = hVertProg = hFragProg = 0; hShader = hVertProg = hFragProg = 0;
currentglowstate = 0;
currentsplitstate = 0;
currentfixedcolormap = 0;
currentTextureMatrixState = true; // by setting the matrix state to 'true' it is guaranteed to be set the first time the render state gets applied.
currentModelMatrixState = true;
} }
~FShader(); ~FShader();

View file

@ -8,6 +8,7 @@ uniform vec4 uCameraPos;
uniform int uTextureMode; uniform int uTextureMode;
uniform float uClipHeight, uClipHeightDirection; uniform float uClipHeight, uClipHeightDirection;
uniform vec2 uClipSplit; uniform vec2 uClipSplit;
uniform vec4 uClipLine;
uniform float uAlphaThreshold; uniform float uAlphaThreshold;