- removed old immediate mode path for generating stencils.

This commit is contained in:
Christoph Oelckers 2014-06-15 10:15:44 +02:00
parent 3644073bbd
commit 1b91a8f88c
3 changed files with 63 additions and 100 deletions

View file

@ -139,66 +139,36 @@ void GLPortal::ClearScreen()
//-----------------------------------------------------------------------------
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++)
{
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
// (cheap ass version)
glBegin(GL_TRIANGLE_FAN);
glVertex3f(-32767.0f, 32767.0f, -32767.0f);
glVertex3f(-32767.0f, 32767.0f, 32767.0f);
glVertex3f(32767.0f, 32767.0f, 32767.0f);
glVertex3f(32767.0f, 32767.0f, -32767.0f);
glEnd();
glBegin(GL_TRIANGLE_FAN);
glVertex3f(-32767.0f, -32767.0f, -32767.0f);
glVertex3f(-32767.0f, -32767.0f, 32767.0f);
glVertex3f(32767.0f, -32767.0f, 32767.0f);
glVertex3f(32767.0f, -32767.0f, -32767.0f);
glEnd();
// Cap the stencil at the top and bottom
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]);
}
}
else
for (unsigned int i = 0; i < mPrimIndices.Size(); i += 2)
{
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++)
{
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]);
}
GLRenderer->mVBO->RenderArray(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)
{
glBeginQuery(GL_SAMPLES_PASSED_ARB, QueryObject);
glBeginQuery(GL_SAMPLES_PASSED, QueryObject);
}
else doquery = false; // some kind of error happened
DrawPortalStencil();
glEndQuery(GL_SAMPLES_PASSED_ARB);
glEndQuery(GL_SAMPLES_PASSED);
// Clear Z-buffer
glStencilFunc(GL_EQUAL,recursion+1,~0); // draw sky into stencil
@ -268,7 +238,7 @@ bool GLPortal::Start(bool usestencil, bool doquery)
GLuint sampleCount;
glGetQueryObjectuiv(QueryObject, GL_QUERY_RESULT_ARB, &sampleCount);
glGetQueryObjectuiv(QueryObject, GL_QUERY_RESULT, &sampleCount);
if (sampleCount==0) // not visible
{

View file

@ -104,6 +104,16 @@ public:
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 class GLPortal;
@ -159,8 +169,7 @@ private:
void SetupLights();
bool PrepareLight(texcoord * tcs, ADynamicLight * light);
void RenderWall(int textured, ADynamicLight * light=NULL);
void GetPrimitive(unsigned int *store);
void RenderWall(int textured, ADynamicLight * light=NULL, unsigned int *store = NULL);
void FloodPlane(int pass);

View file

@ -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];
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)
{
@ -234,7 +234,7 @@ void GLWall::RenderWall(int textured, ADynamicLight * light)
tcs[1]=uplft;
tcs[2]=uprgt;
tcs[3]=lorgt;
if (!!(flags&GLWF_GLOW) && (textured & 2))
if ((flags&GLWF_GLOW) && (textured & RWF_GLOW))
{
gl_RenderState.SetGlowPlanes(topplane, bottomplane);
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
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
unsigned int count, offset;
ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[0].u, tcs[0].v);
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++;
if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs, ptr);
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
vertexcount += 4;
count = GLRenderer->mVBO->GetCount(ptr, &offset);
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_RenderState.SetEffect(EFF_FOGBOUNDARY);
gl_RenderState.EnableAlphaTest(false);
RenderWall(0);
RenderWall(RWF_BLANK);
gl_RenderState.EnableAlphaTest(true);
gl_RenderState.SetEffect(EFF_NONE);
}
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.
float fogdensity=gl_GetFogDensity(lightlevel, Colormap.FadeColor);
@ -392,7 +376,7 @@ void GLWall::RenderMirrorSurface()
pat->BindPatch(0);
flags &= ~GLWF_GLOW;
RenderWall(0);
RenderWall(RWF_BLANK);
gl_RenderState.SetEffect(EFF_NONE);
@ -453,7 +437,7 @@ void GLWall::RenderTranslucentWall()
if (type!=RENDERWALL_M2SNF) gl_SetFog(lightlevel, extra, &Colormap, isadditive);
else gl_SetFog(255, 0, NULL, false);
RenderWall(5);
RenderWall(RWF_TEXTURED|RWF_NOSPLIT);
// restore default settings
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));
gltexture->Bind(flags, 0);
RenderWall(3);
RenderWall(RWF_TEXTURED|RWF_GLOW);
gl_RenderState.EnableGlow(false);
gl_RenderState.EnableLight(false);
break;
@ -528,14 +512,14 @@ void GLWall::Draw(int pass)
{
gltexture->Bind(flags, 0);
}
RenderWall(pass == GLPASS_BASE? 2:3);
RenderWall(RWF_TEXTURED|RWF_GLOW);
gl_RenderState.EnableGlow(false);
gl_RenderState.EnableLight(false);
break;
case GLPASS_TEXTURE: // modulated texture
gltexture->Bind(flags, 0);
RenderWall(1);
RenderWall(RWF_TEXTURED);
break;
case GLPASS_LIGHT:
@ -564,7 +548,7 @@ void GLWall::Draw(int pass)
if (!(node->lightsource->flags2&MF2_DORMANT))
{
iter_dlight++;
RenderWall(1, node->lightsource);
RenderWall(RWF_TEXTURED, node->lightsource);
}
node = node->nextLight;
}