mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 13:01:47 +00:00
- preparations for using clip planes on line portals.
This commit is contained in:
parent
e3fad118d2
commit
21283b18f4
12 changed files with 133 additions and 70 deletions
|
@ -84,6 +84,7 @@
|
|||
FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
|
||||
{
|
||||
framebuffer = fb;
|
||||
mClipPortal = NULL;
|
||||
mCurrentPortal = NULL;
|
||||
mMirrorCount = 0;
|
||||
mPlaneMirrorCount = 0;
|
||||
|
|
|
@ -59,6 +59,7 @@ class FGLRenderer
|
|||
public:
|
||||
|
||||
OpenGLFrameBuffer *framebuffer;
|
||||
GLPortal *mClipPortal;
|
||||
GLPortal *mCurrentPortal;
|
||||
int mMirrorCount;
|
||||
int mPlaneMirrorCount;
|
||||
|
|
|
@ -69,7 +69,7 @@ TArray<VSMatrix> gl_MatrixStack;
|
|||
void FRenderState::Reset()
|
||||
{
|
||||
mTextureEnabled = true;
|
||||
mSplitEnabled = mBrightmapEnabled = mFogEnabled = mGlowEnabled = false;
|
||||
mClipLineEnabled = mSplitEnabled = mBrightmapEnabled = mFogEnabled = mGlowEnabled = false;
|
||||
mColorMask[0] = mColorMask[1] = mColorMask[2] = mColorMask[3] = true;
|
||||
currentColorMask[0] = currentColorMask[1] = currentColorMask[2] = currentColorMask[3] = true;
|
||||
mFogColor.d = -1;
|
||||
|
@ -171,10 +171,22 @@ bool FRenderState::ApplyShader()
|
|||
activeShader->muSplitBottomPlane.Set(mSplitBottomPlane.vec);
|
||||
activeShader->currentsplitstate = 1;
|
||||
}
|
||||
else
|
||||
else if (activeShader->currentsplitstate)
|
||||
{
|
||||
activeShader->muSplitTopPlane.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)
|
||||
|
|
|
@ -47,6 +47,7 @@ class FRenderState
|
|||
bool mFogEnabled;
|
||||
bool mGlowEnabled;
|
||||
bool mSplitEnabled;
|
||||
bool mClipLineEnabled;
|
||||
bool mBrightmapEnabled;
|
||||
bool mColorMask[4];
|
||||
bool currentColorMask[4];
|
||||
|
@ -73,6 +74,7 @@ class FRenderState
|
|||
FStateVec4 mGlowTop, mGlowBottom;
|
||||
FStateVec4 mGlowTopPlane, mGlowBottomPlane;
|
||||
FStateVec4 mSplitTopPlane, mSplitBottomPlane;
|
||||
FStateVec4 mClipLine;
|
||||
PalEntry mFogColor;
|
||||
PalEntry mObjectColor;
|
||||
FStateVec4 mDynColor;
|
||||
|
@ -145,6 +147,16 @@ public:
|
|||
return mClipHeightDirection;
|
||||
}
|
||||
|
||||
FStateVec4 &GetClipLine()
|
||||
{
|
||||
return mClipLine;
|
||||
}
|
||||
|
||||
bool GetClipLineState()
|
||||
{
|
||||
return mClipLineEnabled;
|
||||
}
|
||||
|
||||
void SetClipHeight(float height, float direction);
|
||||
|
||||
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)
|
||||
{
|
||||
mLightIndex = n;
|
||||
|
|
|
@ -111,7 +111,7 @@ static void AddLine (seg_t *seg, bool portalclip)
|
|||
|
||||
if (portalclip)
|
||||
{
|
||||
int clipres = GLRenderer->mCurrentPortal->ClipSeg(seg);
|
||||
int clipres = GLRenderer->mClipPortal->ClipSeg(seg);
|
||||
if (clipres == GLPortal::PClip_InFront) return;
|
||||
}
|
||||
|
||||
|
@ -218,7 +218,7 @@ static void PolySubsector(subsector_t * sub)
|
|||
{
|
||||
if (line->linedef)
|
||||
{
|
||||
AddLine (line, GLRenderer->mCurrentPortal != NULL);
|
||||
AddLine (line, GLRenderer->mClipPortal != NULL);
|
||||
}
|
||||
line++;
|
||||
}
|
||||
|
@ -313,11 +313,11 @@ static inline void AddLines(subsector_t * sub, sector_t * sector)
|
|||
{
|
||||
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))
|
||||
{
|
||||
AddLine (seg, GLRenderer->mCurrentPortal != NULL);
|
||||
AddLine (seg, GLRenderer->mClipPortal != NULL);
|
||||
}
|
||||
seg++;
|
||||
}
|
||||
|
@ -447,12 +447,12 @@ static void DoSubsector(subsector_t * sub)
|
|||
|
||||
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)
|
||||
{
|
||||
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.
|
||||
if (line) AddSpecialPortalLines(sub, fakesector, line);
|
||||
return;
|
||||
|
|
|
@ -300,9 +300,6 @@ bool GLPortal::Start(bool usestencil, bool doquery)
|
|||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
}
|
||||
planestack.Push(gl_RenderState.GetClipHeight());
|
||||
planestack.Push(gl_RenderState.GetClipHeightDirection());
|
||||
gl_RenderState.SetClipHeight(0., 0.);
|
||||
|
||||
// save viewpoint
|
||||
savedViewPos = ViewPos;
|
||||
|
@ -313,8 +310,12 @@ bool GLPortal::Start(bool usestencil, bool doquery)
|
|||
savedviewpath[0] = ViewPath[0];
|
||||
savedviewpath[1] = ViewPath[1];
|
||||
|
||||
NextPortal = GLRenderer->mCurrentPortal;
|
||||
GLRenderer->mCurrentPortal = NULL; // Portals which need this have to set it themselves
|
||||
PrevPortal = GLRenderer->mCurrentPortal;
|
||||
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();
|
||||
return true;
|
||||
}
|
||||
|
@ -359,12 +360,9 @@ void GLPortal::End(bool usestencil)
|
|||
bool needdepth = NeedDepthBuffer();
|
||||
|
||||
PortalAll.Clock();
|
||||
GLRenderer->mCurrentPortal = NextPortal;
|
||||
|
||||
float f, d;
|
||||
planestack.Pop(d);
|
||||
planestack.Pop(f);
|
||||
gl_RenderState.SetClipHeight(f, d);
|
||||
if (PrevPortal != NULL) PrevPortal->PopState();
|
||||
GLRenderer->mCurrentPortal = PrevPortal;
|
||||
GLRenderer->mClipPortal = PrevClipPortal;
|
||||
|
||||
if (usestencil)
|
||||
{
|
||||
|
@ -806,14 +804,59 @@ void GLPlaneMirrorPortal::DrawContents()
|
|||
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;
|
||||
}
|
||||
|
||||
GLRenderer->mCurrentPortal = this;
|
||||
GLRenderer->mClipPortal = this;
|
||||
DAngle StartAngle = ViewAngle;
|
||||
DVector3 StartPos = ViewPos;
|
||||
|
||||
|
@ -910,37 +953,6 @@ void GLMirrorPortal::DrawContents()
|
|||
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;
|
||||
}
|
||||
|
||||
GLRenderer->mCurrentPortal = this;
|
||||
GLRenderer->mClipPortal = this;
|
||||
|
||||
line_t *origin = glport->reference->mOrigin;
|
||||
P_TranslatePortalXY(origin, ViewPos.X, ViewPos.Y);
|
||||
|
|
|
@ -107,7 +107,8 @@ private:
|
|||
area_t savedviewarea;
|
||||
bool savedshowviewer;
|
||||
DVector3 savedviewpath[2];
|
||||
GLPortal *NextPortal;
|
||||
GLPortal *PrevPortal;
|
||||
GLPortal *PrevClipPortal;
|
||||
TArray<BYTE> savedmapsection;
|
||||
TArray<unsigned int> mPrimIndices;
|
||||
|
||||
|
@ -130,6 +131,8 @@ protected:
|
|||
virtual const char *GetName() = 0;
|
||||
void SaveMapSection();
|
||||
void RestoreMapSection();
|
||||
virtual void PushState() {}
|
||||
virtual void PopState() {}
|
||||
|
||||
public:
|
||||
|
||||
|
@ -341,6 +344,8 @@ protected:
|
|||
virtual void DrawContents();
|
||||
virtual void * GetSource() const { return origin; }
|
||||
virtual const char *GetName();
|
||||
virtual void PushState();
|
||||
virtual void PopState();
|
||||
secplane_t * origin;
|
||||
|
||||
public:
|
||||
|
|
|
@ -503,7 +503,7 @@ void FGLRenderer::DrawScene(bool toscreen)
|
|||
static int recursion=0;
|
||||
|
||||
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
|
||||
// with swapping the render buffer until now.
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
|
||||
if (GLRenderer->mCurrentPortal)
|
||||
if (GLRenderer->mClipPortal)
|
||||
{
|
||||
int clipres = GLRenderer->mCurrentPortal->ClipPoint(thingpos);
|
||||
int clipres = GLRenderer->mClipPortal->ClipPoint(thingpos);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -278,6 +278,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
|||
muGlowTopPlane.Init(hShader, "uGlowTopPlane");
|
||||
muSplitBottomPlane.Init(hShader, "uSplitBottomPlane");
|
||||
muSplitTopPlane.Init(hShader, "uSplitTopPlane");
|
||||
muClipLine.Init(hShader, "uClipLine");
|
||||
muFixedColormap.Init(hShader, "uFixedColormap");
|
||||
muInterpolationFactor.Init(hShader, "uInterpolationFactor");
|
||||
muClipHeight.Init(hShader, "uClipHeight");
|
||||
|
|
|
@ -220,6 +220,7 @@ class FShader
|
|||
FUniform4f muGlowTopPlane;
|
||||
FUniform4f muSplitBottomPlane;
|
||||
FUniform4f muSplitTopPlane;
|
||||
FUniform4f muClipLine;
|
||||
FBufferedUniform1f muInterpolationFactor;
|
||||
FBufferedUniform1f muClipHeight;
|
||||
FBufferedUniform1f muClipHeightDirection;
|
||||
|
@ -234,22 +235,18 @@ class FShader
|
|||
public:
|
||||
int fakevb_index;
|
||||
private:
|
||||
int currentglowstate;
|
||||
int currentsplitstate;
|
||||
int currentfixedcolormap;
|
||||
bool currentTextureMatrixState;
|
||||
bool currentModelMatrixState;
|
||||
int currentglowstate = 0;
|
||||
int currentsplitstate = 0;
|
||||
int currentcliplinestate = 0;
|
||||
int currentfixedcolormap = 0;
|
||||
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:
|
||||
FShader(const char *name)
|
||||
: mName(name)
|
||||
{
|
||||
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();
|
||||
|
|
|
@ -8,6 +8,7 @@ uniform vec4 uCameraPos;
|
|||
uniform int uTextureMode;
|
||||
uniform float uClipHeight, uClipHeightDirection;
|
||||
uniform vec2 uClipSplit;
|
||||
uniform vec4 uClipLine;
|
||||
|
||||
uniform float uAlphaThreshold;
|
||||
|
||||
|
|
Loading…
Reference in a new issue