diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index 9c5212468..568a2e3f2 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -68,7 +68,6 @@ static inline float GetTimeFloat() CVAR(Bool, gl_interpolate_model_frames, true, CVAR_ARCHIVE) CVAR(Bool, gl_light_models, true, CVAR_ARCHIVE) EXTERN_CVAR(Int, gl_fogmode) -EXTERN_CVAR(Bool, gl_dynlight_shader) extern TDeletingArray Voxels; extern TDeletingArray VoxelDefs; diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index b49b0027d..18c6dcff5 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -54,6 +54,7 @@ #include "gl/renderer/gl_renderstate.h" #include "gl/dynlights/gl_glow.h" #include "gl/data/gl_data.h" +#include "gl/data/gl_vertexbuffer.h" #include "gl/scene/gl_clipper.h" #include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_portal.h" @@ -138,33 +139,74 @@ void GLPortal::ClearScreen() //----------------------------------------------------------------------------- void GLPortal::DrawPortalStencil() { - for(unsigned int i=0;i 1) + { + // 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(); + } } - - if (NeedCap() && lines.Size() > 1) + else { - // 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(); + if (mPrimIndices.Size() == 0) + { + bool cap = NeedCap() && lines.Size() > 1; + mPrimIndices.Resize(2 * lines.Size() + 4 * cap); + + for (unsigned int i = 0; imVBO->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]); + } } } + + + //----------------------------------------------------------------------------- // // Start diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index b04873ec8..970fc3523 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -104,6 +104,7 @@ private: unsigned char clipsave; GLPortal *NextPortal; TArray savedmapsection; + TArray mPrimIndices; protected: TArray lines; diff --git a/src/gl/scene/gl_vertex.cpp b/src/gl/scene/gl_vertex.cpp index 03f7df520..b3ee9c8b5 100644 --- a/src/gl/scene/gl_vertex.cpp +++ b/src/gl/scene/gl_vertex.cpp @@ -89,6 +89,116 @@ void GLWall::SplitUpperEdge(texcoord * tcs) vertexcount += sidedef->numsegs-1; } +//========================================================================== +// +// Split upper edge of wall +// +//========================================================================== + +void GLWall::SplitLowerEdge(texcoord * tcs) +{ + if (seg == NULL || seg->sidedef == NULL || (seg->sidedef->Flags & WALLF_POLYOBJ) || seg->sidedef->numsegs == 1) return; + + side_t *sidedef = seg->sidedef; + float polyw = glseg.fracright - glseg.fracleft; + float facu = (tcs[3].u - tcs[0].u) / polyw; + float facv = (tcs[3].v - tcs[0].v) / polyw; + float facb = (zbottom[1] - zbottom[0]) / polyw; + float facc = (zceil[1] - zceil[0]) / polyw; + float facf = (zfloor[1] - zfloor[0]) / polyw; + + for (int i = sidedef->numsegs-2; i >= 0; i--) + { + seg_t *cseg = sidedef->segs[i]; + float sidefrac = cseg->sidefrac; + if (sidefrac >= glseg.fracright) continue; + if (sidefrac <= glseg.fracleft) return; + + float fracfac = sidefrac - glseg.fracleft; + + glTexCoord2f(tcs[0].u + facu * fracfac, tcs[0].v + facv * fracfac); + glVertex3f(cseg->v2->fx, zbottom[0] + facb * fracfac, cseg->v2->fy); + } + vertexcount += sidedef->numsegs-1; +} + +//========================================================================== +// +// Split left edge of wall +// +//========================================================================== + +void GLWall::SplitLeftEdge(texcoord * tcs) +{ + if (vertexes[0]==NULL) return; + + vertex_t * vi=vertexes[0]; + + if (vi->numheights) + { + int i=0; + + float polyh1=ztop[0] - zbottom[0]; + float factv1=polyh1? (tcs[1].v - tcs[0].v) / polyh1:0; + float factu1=polyh1? (tcs[1].u - tcs[0].u) / polyh1:0; + + while (inumheights && vi->heightlist[i] <= zbottom[0] ) i++; + while (inumheights && vi->heightlist[i] < ztop[0]) + { + glTexCoord2f(factu1*(vi->heightlist[i] - ztop[0]) + tcs[1].u, + factv1*(vi->heightlist[i] - ztop[0]) + tcs[1].v); + glVertex3f(glseg.x1, vi->heightlist[i], glseg.y1); + i++; + } + vertexcount+=i; + } +} + +//========================================================================== +// +// Split right edge of wall +// +//========================================================================== + +void GLWall::SplitRightEdge(texcoord * tcs) +{ + if (vertexes[1]==NULL) return; + + vertex_t * vi=vertexes[1]; + + if (vi->numheights) + { + int i=vi->numheights-1; + + float polyh2 = ztop[1] - zbottom[1]; + float factv2 = polyh2? (tcs[2].v - tcs[3].v) / polyh2:0; + float factu2 = polyh2? (tcs[2].u - tcs[3].u) / polyh2:0; + + while (i>0 && vi->heightlist[i] >= ztop[1]) i--; + while (i>0 && vi->heightlist[i] > zbottom[1]) + { + glTexCoord2f(factu2 * (vi->heightlist[i] - ztop[1]) + tcs[2].u, + factv2 * (vi->heightlist[i] - ztop[1]) + tcs[2].v); + glVertex3f(glseg.x2, vi->heightlist[i], glseg.y2); + i--; + } + vertexcount+=i; + } +} + + +//========================================================================== +// +// same for vertex buffer mode +// +//========================================================================== + +//========================================================================== +// +// Split upper edge of wall +// +//========================================================================== + void GLWall::SplitUpperEdge(texcoord * tcs, FFlatVertex *&ptr) { if (seg == NULL || seg->sidedef == NULL || (seg->sidedef->Flags & WALLF_POLYOBJ) || seg->sidedef->numsegs == 1) return; @@ -126,33 +236,6 @@ void GLWall::SplitUpperEdge(texcoord * tcs, FFlatVertex *&ptr) // //========================================================================== -void GLWall::SplitLowerEdge(texcoord * tcs) -{ - if (seg == NULL || seg->sidedef == NULL || (seg->sidedef->Flags & WALLF_POLYOBJ) || seg->sidedef->numsegs == 1) return; - - side_t *sidedef = seg->sidedef; - float polyw = glseg.fracright - glseg.fracleft; - float facu = (tcs[3].u - tcs[0].u) / polyw; - float facv = (tcs[3].v - tcs[0].v) / polyw; - float facb = (zbottom[1] - zbottom[0]) / polyw; - float facc = (zceil[1] - zceil[0]) / polyw; - float facf = (zfloor[1] - zfloor[0]) / polyw; - - for (int i = sidedef->numsegs-2; i >= 0; i--) - { - seg_t *cseg = sidedef->segs[i]; - float sidefrac = cseg->sidefrac; - if (sidefrac >= glseg.fracright) continue; - if (sidefrac <= glseg.fracleft) return; - - float fracfac = sidefrac - glseg.fracleft; - - glTexCoord2f(tcs[0].u + facu * fracfac, tcs[0].v + facv * fracfac); - glVertex3f(cseg->v2->fx, zbottom[0] + facb * fracfac, cseg->v2->fy); - } - vertexcount += sidedef->numsegs-1; -} - void GLWall::SplitLowerEdge(texcoord * tcs, FFlatVertex *&ptr) { if (seg == NULL || seg->sidedef == NULL || (seg->sidedef->Flags & WALLF_POLYOBJ) || seg->sidedef->numsegs == 1) return; @@ -190,32 +273,6 @@ void GLWall::SplitLowerEdge(texcoord * tcs, FFlatVertex *&ptr) // //========================================================================== -void GLWall::SplitLeftEdge(texcoord * tcs) -{ - if (vertexes[0]==NULL) return; - - vertex_t * vi=vertexes[0]; - - if (vi->numheights) - { - int i=0; - - float polyh1=ztop[0] - zbottom[0]; - float factv1=polyh1? (tcs[1].v - tcs[0].v) / polyh1:0; - float factu1=polyh1? (tcs[1].u - tcs[0].u) / polyh1:0; - - while (inumheights && vi->heightlist[i] <= zbottom[0] ) i++; - while (inumheights && vi->heightlist[i] < ztop[0]) - { - glTexCoord2f(factu1*(vi->heightlist[i] - ztop[0]) + tcs[1].u, - factv1*(vi->heightlist[i] - ztop[0]) + tcs[1].v); - glVertex3f(glseg.x1, vi->heightlist[i], glseg.y1); - i++; - } - vertexcount+=i; - } -} - void GLWall::SplitLeftEdge(texcoord * tcs, FFlatVertex *&ptr) { if (vertexes[0] == NULL) return; @@ -251,32 +308,6 @@ void GLWall::SplitLeftEdge(texcoord * tcs, FFlatVertex *&ptr) // //========================================================================== -void GLWall::SplitRightEdge(texcoord * tcs) -{ - if (vertexes[1]==NULL) return; - - vertex_t * vi=vertexes[1]; - - if (vi->numheights) - { - int i=vi->numheights-1; - - float polyh2 = ztop[1] - zbottom[1]; - float factv2 = polyh2? (tcs[2].v - tcs[3].v) / polyh2:0; - float factu2 = polyh2? (tcs[2].u - tcs[3].u) / polyh2:0; - - while (i>0 && vi->heightlist[i] >= ztop[1]) i--; - while (i>0 && vi->heightlist[i] > zbottom[1]) - { - glTexCoord2f(factu2 * (vi->heightlist[i] - ztop[1]) + tcs[2].u, - factv2 * (vi->heightlist[i] - ztop[1]) + tcs[2].v); - glVertex3f(glseg.x2, vi->heightlist[i], glseg.y2); - i--; - } - vertexcount+=i; - } -} - void GLWall::SplitRightEdge(texcoord * tcs, FFlatVertex *&ptr) { if (vertexes[1] == NULL) return; diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index a9d0c1087..dd1365193 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -160,6 +160,7 @@ private: void SetupLights(); bool PrepareLight(texcoord * tcs, ADynamicLight * light); void RenderWall(int textured, float * color2, ADynamicLight * light=NULL); + void GetPrimitive(unsigned int *store); void FloodPlane(int pass); diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 98ae66800..9c5baae6a 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -309,6 +309,36 @@ void GLWall::RenderWall(int textured, float * color2, ADynamicLight * light) } +//========================================================================== +// +// 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; + } + //========================================================================== // //