mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-23 04:22:34 +00:00
- started with an abstract render interface, most importantly handle the stencil for plane flooding through the render state object instead of changing GL state directly.
This commit is contained in:
parent
510aa600dd
commit
3c3be0d349
7 changed files with 152 additions and 29 deletions
|
@ -38,6 +38,8 @@
|
|||
#include "gl/renderer/gl_renderbuffers.h"
|
||||
#include "gl/textures/gl_hwtexture.h"
|
||||
|
||||
static int op2gl[] = { GL_KEEP, GL_INCR, GL_DECR };
|
||||
|
||||
FGLRenderState gl_RenderState;
|
||||
|
||||
CVAR(Bool, gl_direct_state_change, true, 0)
|
||||
|
@ -226,6 +228,22 @@ void FGLRenderState::Apply()
|
|||
}
|
||||
}
|
||||
|
||||
if (mStencil.mChanged)
|
||||
{
|
||||
int recursion = GLRenderer->mPortalState.GetRecursion();
|
||||
glStencilFunc(GL_EQUAL, recursion + mStencil.mOffsVal, ~0); // draw sky into stencil
|
||||
glStencilOp(GL_KEEP, GL_KEEP, op2gl[mStencil.mOperation]); // this stage doesn't modify the stencil
|
||||
|
||||
bool cmon = !(mStencil.mFlags & SF_ColorMaskOff);
|
||||
glColorMask(cmon, cmon, cmon, cmon); // don't write to the graphics buffer
|
||||
glDepthMask(!(mStencil.mFlags & SF_DepthMaskOff));
|
||||
if (mStencil.mFlags & SF_DepthTestOff)
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
else
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
}
|
||||
|
||||
if (mVertexBuffer != mCurrentVertexBuffer)
|
||||
{
|
||||
if (mVertexBuffer == NULL) glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
|
|
@ -233,6 +233,14 @@ public:
|
|||
return mPassType == GBUFFER_PASS ? 3 : 1;
|
||||
}
|
||||
|
||||
void ApplyMaterial()
|
||||
{
|
||||
if (mMaterial.mChanged)
|
||||
{
|
||||
SetMaterial(mMaterial.mMaterial, mMaterial.mClampMode, mMaterial.mTranslation, mMaterial.mOverrideShader, false);
|
||||
mMaterial.mChanged = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
extern FGLRenderState gl_RenderState;
|
||||
|
|
|
@ -273,5 +273,33 @@ bool FDrawInfo::SetDepthClamp(bool on)
|
|||
return gl_RenderState.SetDepthClamp(on);
|
||||
}
|
||||
|
||||
static int dt2gl[] = { GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_FAN, GL_TRIANGLE_STRIP };
|
||||
|
||||
void FDrawInfo::Draw(EDrawType dt, FRenderState &state, int index, int count, bool apply)
|
||||
{
|
||||
assert(&state == &gl_RenderState);
|
||||
if (apply)
|
||||
{
|
||||
gl_RenderState.ApplyMaterial();
|
||||
gl_RenderState.Apply();
|
||||
}
|
||||
drawcalls.Clock();
|
||||
glDrawArrays(dt2gl[dt], index, count);
|
||||
drawcalls.Unclock();
|
||||
}
|
||||
|
||||
void FDrawInfo::DrawIndexed(EDrawType dt, FRenderState &state, int index, int count, bool apply)
|
||||
{
|
||||
assert(&state == &gl_RenderState);
|
||||
if (apply)
|
||||
{
|
||||
gl_RenderState.ApplyMaterial();
|
||||
gl_RenderState.Apply();
|
||||
}
|
||||
drawcalls.Clock();
|
||||
glDrawElements(dt2gl[dt], count, GL_UNSIGNED_INT, GLRenderer->mVBO->GetIndexPointer() + index);
|
||||
drawcalls.Unclock();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -52,6 +52,9 @@ struct FDrawInfo : public HWDrawInfo
|
|||
std::pair<FFlatVertex *, unsigned int> AllocVertices(unsigned int count) override;
|
||||
int UploadLights(FDynLightData &data) override;
|
||||
|
||||
void Draw(EDrawType dt, FRenderState &state, int index, int count, bool apply = true);
|
||||
void DrawIndexed(EDrawType dt, FRenderState &state, int index, int count, bool apply = true);
|
||||
|
||||
void DrawDecal(GLDecal *gldecal);
|
||||
void DrawDecals();
|
||||
void DrawDecalsForMirror(GLWall *wall);
|
||||
|
|
|
@ -69,9 +69,7 @@ void FDrawInfo::DrawSubsectors(GLFlat *flat, int pass, bool istrans)
|
|||
gl_RenderState.ApplyLightIndex(flat->dynlightindex);
|
||||
if (vcount > 0 && !ClipLineShouldBeActive())
|
||||
{
|
||||
drawcalls.Clock();
|
||||
glDrawElements(GL_TRIANGLES, vcount, GL_UNSIGNED_INT, GLRenderer->mVBO->GetIndexPointer() + iboindex);
|
||||
drawcalls.Unclock();
|
||||
DrawIndexed(DT_Triangles, gl_RenderState, iboindex, vcount);
|
||||
flatvertices += vcount;
|
||||
flatprimitives++;
|
||||
}
|
||||
|
@ -85,8 +83,7 @@ void FDrawInfo::DrawSubsectors(GLFlat *flat, int pass, bool istrans)
|
|||
|
||||
if (ss_renderflags[sub->Index()] & flat->renderflags || istrans)
|
||||
{
|
||||
drawcalls.Clock();
|
||||
glDrawElements(GL_TRIANGLES, (sub->numlines - 2) * 3, GL_UNSIGNED_INT, GLRenderer->mVBO->GetIndexPointer() + index);
|
||||
DrawIndexed(DT_Triangles, gl_RenderState, index, (sub->numlines - 2) * 3, false);
|
||||
drawcalls.Unclock();
|
||||
flatvertices += sub->numlines;
|
||||
flatprimitives++;
|
||||
|
@ -108,7 +105,7 @@ void FDrawInfo::DrawSubsectors(GLFlat *flat, int pass, bool istrans)
|
|||
auto num = node->sub->numlines;
|
||||
flatvertices += num;
|
||||
flatprimitives++;
|
||||
glDrawArrays(GL_TRIANGLE_FAN, node->vertexindex, num);
|
||||
Draw(DT_TriangleFan, gl_RenderState, node->vertexindex, num);
|
||||
node = node->next;
|
||||
}
|
||||
// Flood gaps with the back side's ceiling/floor texture
|
||||
|
@ -130,7 +127,7 @@ void FDrawInfo::DrawSubsectors(GLFlat *flat, int pass, bool istrans)
|
|||
glPolygonOffset(1.0f, 128.0f);
|
||||
|
||||
SetupFloodStencil(fnode->vertexindex);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, fnode->vertexindex + 4, 4);
|
||||
Draw(DT_TriangleFan, gl_RenderState, fnode->vertexindex + 4, 4);
|
||||
ClearFloodStencil(fnode->vertexindex);
|
||||
|
||||
glPolygonOffset(0.0f, 0.0f);
|
||||
|
@ -156,21 +153,12 @@ void FDrawInfo::SetupFloodStencil(int vindex)
|
|||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.Apply();
|
||||
|
||||
glStencilFunc(GL_EQUAL, recursion, ~0); // create stencil
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); // increment stencil of valid pixels
|
||||
gl_RenderState.SetStencil(0, SOP_Increment, SF_ColorMaskOff);
|
||||
|
||||
glColorMask(0, 0, 0, 0); // don't write to the graphics buffer
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(true);
|
||||
Draw(DT_TriangleFan, gl_RenderState, vindex, 4);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_FAN, vindex, 4);
|
||||
gl_RenderState.SetStencil(1, SOP_Keep, SF_DepthMaskOff | SF_DepthTestOff);
|
||||
|
||||
glStencilFunc(GL_EQUAL, recursion + 1, ~0); // draw sky into stencil
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // this stage doesn't modify the stencil
|
||||
|
||||
glColorMask(1, 1, 1, 1); // don't write to the graphics buffer
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(false);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
gl_RenderState.Apply();
|
||||
|
@ -183,18 +171,13 @@ void FDrawInfo::ClearFloodStencil(int vindex)
|
|||
gl_RenderState.SetEffect(EFF_STENCIL);
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.Apply();
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
|
||||
// Use revertible color mask, to avoid stomping on anaglyph 3D state
|
||||
glColorMask(0, 0, 0, 0); // don't write to the graphics buffer
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_FAN, vindex, 4);
|
||||
gl_RenderState.SetStencil(1, SOP_Decrement, SF_ColorMaskOff | SF_DepthMaskOff | SF_DepthTestOff);
|
||||
|
||||
Draw(DT_TriangleFan, gl_RenderState, vindex, 4);
|
||||
|
||||
// restore old stencil op.
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
glStencilFunc(GL_EQUAL, recursion, ~0);
|
||||
glColorMask(1, 1, 1, 1);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(true);
|
||||
gl_RenderState.SetStencil(0, SOP_Keep, SF_AllOn);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,14 @@
|
|||
#include "hw_viewpointuniforms.h"
|
||||
#include "v_video.h"
|
||||
|
||||
enum EDrawType
|
||||
{
|
||||
DT_Points = 0,
|
||||
DT_Lines = 1,
|
||||
DT_Triangles = 2,
|
||||
DT_TriangleFan = 3,
|
||||
DT_TriangleStrip = 4
|
||||
};
|
||||
|
||||
struct FSectorPortalGroup;
|
||||
struct FLinePortalSpan;
|
||||
|
@ -24,6 +32,7 @@ class IPortal;
|
|||
class FFlatVertexGenerator;
|
||||
class IRenderQueue;
|
||||
class HWScenePortalBase;
|
||||
class FRenderState;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -295,5 +304,9 @@ public:
|
|||
|
||||
virtual GLDecal *AddDecal(bool onmirror) = 0;
|
||||
virtual std::pair<FFlatVertex *, unsigned int> AllocVertices(unsigned int count) = 0;
|
||||
|
||||
virtual void Draw(EDrawType dt, FRenderState &state, int index, int count, bool apply = true) = 0;
|
||||
virtual void DrawIndexed(EDrawType dt, FRenderState &state, int index, int count, bool apply = true) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "vectors.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "r_data/matrix.h"
|
||||
#include "hwrenderer/textures/hw_material.h"
|
||||
|
||||
struct FColormap;
|
||||
|
||||
|
@ -18,12 +19,27 @@ enum EEffect
|
|||
MAX_EFFECTS
|
||||
};
|
||||
|
||||
enum
|
||||
enum EAlphaFunc
|
||||
{
|
||||
Alpha_GEqual = 0,
|
||||
Alpha_Greater = 1
|
||||
};
|
||||
|
||||
enum EStencilOp
|
||||
{
|
||||
SOP_Keep = 0,
|
||||
SOP_Increment = 1,
|
||||
SOP_Decrement = 2
|
||||
};
|
||||
|
||||
enum EStencilFlags
|
||||
{
|
||||
SF_AllOn = 0,
|
||||
SF_ColorMaskOff = 1,
|
||||
SF_DepthMaskOff = 2,
|
||||
SF_DepthTestOff = 4
|
||||
};
|
||||
|
||||
struct FStateVec4
|
||||
{
|
||||
float vec[4];
|
||||
|
@ -37,6 +53,40 @@ struct FStateVec4
|
|||
}
|
||||
};
|
||||
|
||||
struct FMaterialState
|
||||
{
|
||||
FMaterial *mMaterial;
|
||||
int mClampMode;
|
||||
int mTranslation;
|
||||
int mOverrideShader;
|
||||
bool mChanged;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
mMaterial = nullptr;
|
||||
mTranslation = 0;
|
||||
mClampMode = CLAMP_NONE;
|
||||
mOverrideShader = -1;
|
||||
mChanged = false;
|
||||
}
|
||||
};
|
||||
|
||||
struct FStencilState
|
||||
{
|
||||
int mOffsVal;
|
||||
int mOperation;
|
||||
int mFlags;
|
||||
bool mChanged;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
mOffsVal = 0;
|
||||
mOperation = SOP_Keep;
|
||||
mFlags = SF_AllOn;
|
||||
mChanged = false;
|
||||
}
|
||||
};
|
||||
|
||||
class FRenderState
|
||||
{
|
||||
protected:
|
||||
|
@ -66,6 +116,8 @@ protected:
|
|||
PalEntry mObjectColor2;
|
||||
FStateVec4 mDynColor;
|
||||
|
||||
FMaterialState mMaterial;
|
||||
FStencilState mStencil;
|
||||
|
||||
// fixed function state
|
||||
float mBias[2];
|
||||
|
@ -95,6 +147,7 @@ public:
|
|||
mSpecialEffect = EFF_NONE;
|
||||
mLightIndex = -1;
|
||||
mBiasOn = false;
|
||||
mMaterial.Reset();
|
||||
|
||||
mColor.Set(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
mGlowTop.Set(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
@ -283,6 +336,23 @@ public:
|
|||
mBiasOn = false;
|
||||
}
|
||||
|
||||
void SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader)
|
||||
{
|
||||
mMaterial.mMaterial = mat;
|
||||
mMaterial.mClampMode = clampmode;
|
||||
mMaterial.mTranslation = translation;
|
||||
mMaterial.mOverrideShader = overrideshader;
|
||||
mMaterial.mChanged = true;
|
||||
}
|
||||
|
||||
void SetStencil(int offs, int op, int flags)
|
||||
{
|
||||
mStencil.mOffsVal = offs;
|
||||
mStencil.mOperation = op;
|
||||
mStencil.mFlags = flags;
|
||||
mStencil.mChanged = true;
|
||||
}
|
||||
|
||||
void SetColor(int sectorlightlevel, int rellight, bool fullbright, const FColormap &cm, float alpha, bool weapon = false);
|
||||
void SetFog(int lightlevel, int rellight, bool fullbright, const FColormap *cmap, bool isadditive);
|
||||
|
||||
|
|
Loading…
Reference in a new issue