mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-11 23:32:02 +00:00
- removed old immediate mode path for generating stencils.
This commit is contained in:
parent
3644073bbd
commit
1b91a8f88c
3 changed files with 63 additions and 100 deletions
|
@ -139,66 +139,36 @@ void GLPortal::ClearScreen()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void GLPortal::DrawPortalStencil()
|
void GLPortal::DrawPortalStencil()
|
||||||
{
|
{
|
||||||
if (!gl_usevbo)
|
if (mPrimIndices.Size() == 0)
|
||||||
{
|
{
|
||||||
|
bool cap = NeedCap() && lines.Size() > 1;
|
||||||
|
mPrimIndices.Resize(2 * lines.Size() + 4 * cap);
|
||||||
|
|
||||||
for (unsigned int i = 0; i<lines.Size(); i++)
|
for (unsigned int i = 0; i<lines.Size(); i++)
|
||||||
{
|
{
|
||||||
lines[i].RenderWall(0, NULL);
|
lines[i].RenderWall(GLWall::RWF_NORENDER, NULL, &mPrimIndices[i * 2]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NeedCap() && lines.Size() > 1)
|
if (cap)
|
||||||
{
|
{
|
||||||
// Cap the stencil at the top and bottom
|
// Cap the stencil at the top and bottom
|
||||||
// (cheap ass version)
|
int n = lines.Size() * 2;
|
||||||
glBegin(GL_TRIANGLE_FAN);
|
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||||
glVertex3f(-32767.0f, 32767.0f, -32767.0f);
|
ptr->Set(-32767.0f, 32767.0f, -32767.0f, 0, 0);
|
||||||
glVertex3f(-32767.0f, 32767.0f, 32767.0f);
|
ptr->Set(-32767.0f, 32767.0f, 32767.0f, 0, 0);
|
||||||
glVertex3f(32767.0f, 32767.0f, 32767.0f);
|
ptr->Set(32767.0f, 32767.0f, 32767.0f, 0, 0);
|
||||||
glVertex3f(32767.0f, 32767.0f, -32767.0f);
|
ptr->Set(32767.0f, 32767.0f, -32767.0f, 0, 0);
|
||||||
glEnd();
|
mPrimIndices[n + 1] = GLRenderer->mVBO->GetCount(ptr, &mPrimIndices[n]);
|
||||||
glBegin(GL_TRIANGLE_FAN);
|
ptr->Set(-32767.0f, -32767.0f, -32767.0f, 0, 0);
|
||||||
glVertex3f(-32767.0f, -32767.0f, -32767.0f);
|
ptr->Set(-32767.0f, -32767.0f, 32767.0f, 0, 0);
|
||||||
glVertex3f(-32767.0f, -32767.0f, 32767.0f);
|
ptr->Set(32767.0f, -32767.0f, 32767.0f, 0, 0);
|
||||||
glVertex3f(32767.0f, -32767.0f, 32767.0f);
|
ptr->Set(32767.0f, -32767.0f, -32767.0f, 0, 0);
|
||||||
glVertex3f(32767.0f, -32767.0f, -32767.0f);
|
mPrimIndices[n + 3] = GLRenderer->mVBO->GetCount(ptr, &mPrimIndices[n + 2]);
|
||||||
glEnd();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
for (unsigned int i = 0; i < mPrimIndices.Size(); i += 2)
|
||||||
{
|
{
|
||||||
if (mPrimIndices.Size() == 0)
|
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, mPrimIndices[i], mPrimIndices[i + 1]);
|
||||||
{
|
|
||||||
bool cap = NeedCap() && lines.Size() > 1;
|
|
||||||
mPrimIndices.Resize(2 * lines.Size() + 4 * cap);
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i<lines.Size(); i++)
|
|
||||||
{
|
|
||||||
lines[i].GetPrimitive(&mPrimIndices[i * 2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cap)
|
|
||||||
{
|
|
||||||
// Cap the stencil at the top and bottom
|
|
||||||
// (cheap ass version)
|
|
||||||
int n = lines.Size() * 2;
|
|
||||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
|
||||||
ptr->Set(-32767.0f, 32767.0f, -32767.0f, 0, 0);
|
|
||||||
ptr->Set(-32767.0f, 32767.0f, 32767.0f, 0, 0);
|
|
||||||
ptr->Set(32767.0f, 32767.0f, 32767.0f, 0, 0);
|
|
||||||
ptr->Set(32767.0f, 32767.0f, -32767.0f, 0, 0);
|
|
||||||
mPrimIndices[n + 1] = GLRenderer->mVBO->GetCount(ptr, &mPrimIndices[n]);
|
|
||||||
ptr->Set(-32767.0f, -32767.0f, -32767.0f, 0, 0);
|
|
||||||
ptr->Set(-32767.0f, -32767.0f, 32767.0f, 0, 0);
|
|
||||||
ptr->Set(32767.0f, -32767.0f, 32767.0f, 0, 0);
|
|
||||||
ptr->Set(32767.0f, -32767.0f, -32767.0f, 0, 0);
|
|
||||||
mPrimIndices[n + 3] = GLRenderer->mVBO->GetCount(ptr, &mPrimIndices[n + 2]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (unsigned int i = 0; i < mPrimIndices.Size(); i += 2)
|
|
||||||
{
|
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, mPrimIndices[i], mPrimIndices[i + 1]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,13 +214,13 @@ bool GLPortal::Start(bool usestencil, bool doquery)
|
||||||
if (!QueryObject) glGenQueries(1, &QueryObject);
|
if (!QueryObject) glGenQueries(1, &QueryObject);
|
||||||
if (QueryObject)
|
if (QueryObject)
|
||||||
{
|
{
|
||||||
glBeginQuery(GL_SAMPLES_PASSED_ARB, QueryObject);
|
glBeginQuery(GL_SAMPLES_PASSED, QueryObject);
|
||||||
}
|
}
|
||||||
else doquery = false; // some kind of error happened
|
else doquery = false; // some kind of error happened
|
||||||
|
|
||||||
DrawPortalStencil();
|
DrawPortalStencil();
|
||||||
|
|
||||||
glEndQuery(GL_SAMPLES_PASSED_ARB);
|
glEndQuery(GL_SAMPLES_PASSED);
|
||||||
|
|
||||||
// Clear Z-buffer
|
// Clear Z-buffer
|
||||||
glStencilFunc(GL_EQUAL,recursion+1,~0); // draw sky into stencil
|
glStencilFunc(GL_EQUAL,recursion+1,~0); // draw sky into stencil
|
||||||
|
@ -268,7 +238,7 @@ bool GLPortal::Start(bool usestencil, bool doquery)
|
||||||
|
|
||||||
GLuint sampleCount;
|
GLuint sampleCount;
|
||||||
|
|
||||||
glGetQueryObjectuiv(QueryObject, GL_QUERY_RESULT_ARB, &sampleCount);
|
glGetQueryObjectuiv(QueryObject, GL_QUERY_RESULT, &sampleCount);
|
||||||
|
|
||||||
if (sampleCount==0) // not visible
|
if (sampleCount==0) // not visible
|
||||||
{
|
{
|
||||||
|
|
|
@ -104,6 +104,16 @@ public:
|
||||||
GLWF_NOSPLITLOWER=128,
|
GLWF_NOSPLITLOWER=128,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
RWF_BLANK = 0,
|
||||||
|
RWF_TEXTURED = 1, // actually not being used anymore because with buffers it's even less efficient not writing the texture coordinates - but leave it here
|
||||||
|
RWF_GLOW = 2,
|
||||||
|
RWF_NOSPLIT = 4,
|
||||||
|
RWF_NORENDER = 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
friend struct GLDrawList;
|
friend struct GLDrawList;
|
||||||
friend class GLPortal;
|
friend class GLPortal;
|
||||||
|
|
||||||
|
@ -159,8 +169,7 @@ private:
|
||||||
|
|
||||||
void SetupLights();
|
void SetupLights();
|
||||||
bool PrepareLight(texcoord * tcs, ADynamicLight * light);
|
bool PrepareLight(texcoord * tcs, ADynamicLight * light);
|
||||||
void RenderWall(int textured, ADynamicLight * light=NULL);
|
void RenderWall(int textured, ADynamicLight * light=NULL, unsigned int *store = NULL);
|
||||||
void GetPrimitive(unsigned int *store);
|
|
||||||
|
|
||||||
void FloodPlane(int pass);
|
void FloodPlane(int pass);
|
||||||
|
|
||||||
|
|
|
@ -223,10 +223,10 @@ void GLWall::SetupLights()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void GLWall::RenderWall(int textured, ADynamicLight * light)
|
void GLWall::RenderWall(int textured, ADynamicLight * light, unsigned int *store)
|
||||||
{
|
{
|
||||||
texcoord tcs[4];
|
texcoord tcs[4];
|
||||||
bool split = (gl_seamless && !(textured&4) && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ));
|
bool split = (gl_seamless && !(textured&RWF_NOSPLIT) && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ));
|
||||||
|
|
||||||
if (!light)
|
if (!light)
|
||||||
{
|
{
|
||||||
|
@ -234,7 +234,7 @@ void GLWall::RenderWall(int textured, ADynamicLight * light)
|
||||||
tcs[1]=uplft;
|
tcs[1]=uplft;
|
||||||
tcs[2]=uprgt;
|
tcs[2]=uprgt;
|
||||||
tcs[3]=lorgt;
|
tcs[3]=lorgt;
|
||||||
if (!!(flags&GLWF_GLOW) && (textured & 2))
|
if ((flags&GLWF_GLOW) && (textured & RWF_GLOW))
|
||||||
{
|
{
|
||||||
gl_RenderState.SetGlowPlanes(topplane, bottomplane);
|
gl_RenderState.SetGlowPlanes(topplane, bottomplane);
|
||||||
gl_RenderState.SetGlowParams(topglowcolor, bottomglowcolor);
|
gl_RenderState.SetGlowParams(topglowcolor, bottomglowcolor);
|
||||||
|
@ -247,10 +247,14 @@ void GLWall::RenderWall(int textured, ADynamicLight * light)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gl_RenderState.Apply();
|
if (!(textured & RWF_NORENDER))
|
||||||
|
{
|
||||||
|
gl_RenderState.Apply();
|
||||||
|
}
|
||||||
|
|
||||||
// the rest of the code is identical for textured rendering and lights
|
// the rest of the code is identical for textured rendering and lights
|
||||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||||
|
unsigned int count, offset;
|
||||||
|
|
||||||
ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[0].u, tcs[0].v);
|
ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[0].u, tcs[0].v);
|
||||||
ptr++;
|
ptr++;
|
||||||
|
@ -264,40 +268,19 @@ void GLWall::RenderWall(int textured, ADynamicLight * light)
|
||||||
ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[3].u, tcs[3].v);
|
ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[3].u, tcs[3].v);
|
||||||
ptr++;
|
ptr++;
|
||||||
if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs, ptr);
|
if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs, ptr);
|
||||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
|
count = GLRenderer->mVBO->GetCount(ptr, &offset);
|
||||||
vertexcount += 4;
|
if (!(textured & RWF_NORENDER))
|
||||||
|
{
|
||||||
|
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, offset, count);
|
||||||
|
vertexcount += count;
|
||||||
|
}
|
||||||
|
if (store != NULL)
|
||||||
|
{
|
||||||
|
store[0] = offset;
|
||||||
|
store[1] = count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// Gets the vertex data for rendering a stencil which needs to be
|
|
||||||
// repeated several times
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void GLWall::GetPrimitive(unsigned int *store)
|
|
||||||
{
|
|
||||||
static texcoord tcs[4] = { 0, 0, 0, 0 };
|
|
||||||
bool split = (gl_seamless && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ));
|
|
||||||
|
|
||||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
|
||||||
|
|
||||||
ptr->Set(glseg.x1, zbottom[0], glseg.y1, 0, 0);
|
|
||||||
ptr++;
|
|
||||||
if (split && glseg.fracleft == 0) SplitLeftEdge(tcs, ptr);
|
|
||||||
ptr->Set(glseg.x1, ztop[0], glseg.y1, 0, 0);
|
|
||||||
ptr++;
|
|
||||||
if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs, ptr);
|
|
||||||
ptr->Set(glseg.x2, ztop[1], glseg.y2, 0, 0);
|
|
||||||
ptr++;
|
|
||||||
if (split && glseg.fracright == 1) SplitRightEdge(tcs, ptr);
|
|
||||||
ptr->Set(glseg.x2, zbottom[1], glseg.y2, 0, 0);
|
|
||||||
ptr++;
|
|
||||||
if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs, ptr);
|
|
||||||
store[1] = GLRenderer->mVBO->GetCount(ptr, &store[0]);
|
|
||||||
vertexcount += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
@ -315,13 +298,14 @@ void GLWall::RenderFogBoundary()
|
||||||
gl_SetFog(lightlevel, rel, &Colormap, false);
|
gl_SetFog(lightlevel, rel, &Colormap, false);
|
||||||
gl_RenderState.SetEffect(EFF_FOGBOUNDARY);
|
gl_RenderState.SetEffect(EFF_FOGBOUNDARY);
|
||||||
gl_RenderState.EnableAlphaTest(false);
|
gl_RenderState.EnableAlphaTest(false);
|
||||||
RenderWall(0);
|
RenderWall(RWF_BLANK);
|
||||||
gl_RenderState.EnableAlphaTest(true);
|
gl_RenderState.EnableAlphaTest(true);
|
||||||
gl_RenderState.SetEffect(EFF_NONE);
|
gl_RenderState.SetEffect(EFF_NONE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// otherwise some approximation is needed. This won't look as good
|
// If we use the fixed function pipeline (GL 2.x)
|
||||||
|
// some approximation is needed. This won't look as good
|
||||||
// as the shader version but it's an acceptable compromise.
|
// as the shader version but it's an acceptable compromise.
|
||||||
float fogdensity=gl_GetFogDensity(lightlevel, Colormap.FadeColor);
|
float fogdensity=gl_GetFogDensity(lightlevel, Colormap.FadeColor);
|
||||||
|
|
||||||
|
@ -392,7 +376,7 @@ void GLWall::RenderMirrorSurface()
|
||||||
pat->BindPatch(0);
|
pat->BindPatch(0);
|
||||||
|
|
||||||
flags &= ~GLWF_GLOW;
|
flags &= ~GLWF_GLOW;
|
||||||
RenderWall(0);
|
RenderWall(RWF_BLANK);
|
||||||
|
|
||||||
gl_RenderState.SetEffect(EFF_NONE);
|
gl_RenderState.SetEffect(EFF_NONE);
|
||||||
|
|
||||||
|
@ -453,7 +437,7 @@ void GLWall::RenderTranslucentWall()
|
||||||
if (type!=RENDERWALL_M2SNF) gl_SetFog(lightlevel, extra, &Colormap, isadditive);
|
if (type!=RENDERWALL_M2SNF) gl_SetFog(lightlevel, extra, &Colormap, isadditive);
|
||||||
else gl_SetFog(255, 0, NULL, false);
|
else gl_SetFog(255, 0, NULL, false);
|
||||||
|
|
||||||
RenderWall(5);
|
RenderWall(RWF_TEXTURED|RWF_NOSPLIT);
|
||||||
|
|
||||||
// restore default settings
|
// restore default settings
|
||||||
if (isadditive) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
if (isadditive) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
@ -507,7 +491,7 @@ void GLWall::Draw(int pass)
|
||||||
|
|
||||||
gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW));
|
gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW));
|
||||||
gltexture->Bind(flags, 0);
|
gltexture->Bind(flags, 0);
|
||||||
RenderWall(3);
|
RenderWall(RWF_TEXTURED|RWF_GLOW);
|
||||||
gl_RenderState.EnableGlow(false);
|
gl_RenderState.EnableGlow(false);
|
||||||
gl_RenderState.EnableLight(false);
|
gl_RenderState.EnableLight(false);
|
||||||
break;
|
break;
|
||||||
|
@ -528,14 +512,14 @@ void GLWall::Draw(int pass)
|
||||||
{
|
{
|
||||||
gltexture->Bind(flags, 0);
|
gltexture->Bind(flags, 0);
|
||||||
}
|
}
|
||||||
RenderWall(pass == GLPASS_BASE? 2:3);
|
RenderWall(RWF_TEXTURED|RWF_GLOW);
|
||||||
gl_RenderState.EnableGlow(false);
|
gl_RenderState.EnableGlow(false);
|
||||||
gl_RenderState.EnableLight(false);
|
gl_RenderState.EnableLight(false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLPASS_TEXTURE: // modulated texture
|
case GLPASS_TEXTURE: // modulated texture
|
||||||
gltexture->Bind(flags, 0);
|
gltexture->Bind(flags, 0);
|
||||||
RenderWall(1);
|
RenderWall(RWF_TEXTURED);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLPASS_LIGHT:
|
case GLPASS_LIGHT:
|
||||||
|
@ -564,7 +548,7 @@ void GLWall::Draw(int pass)
|
||||||
if (!(node->lightsource->flags2&MF2_DORMANT))
|
if (!(node->lightsource->flags2&MF2_DORMANT))
|
||||||
{
|
{
|
||||||
iter_dlight++;
|
iter_dlight++;
|
||||||
RenderWall(1, node->lightsource);
|
RenderWall(RWF_TEXTURED, node->lightsource);
|
||||||
}
|
}
|
||||||
node = node->nextLight;
|
node = node->nextLight;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue