- 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() 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
{ {

View file

@ -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);

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]; 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;
} }