mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-12-01 00:12:27 +00:00
- add vertex buffer based drawing for all walls and flats.
This commit is contained in:
parent
7d3beb665b
commit
f7404d20fb
7 changed files with 273 additions and 30 deletions
|
@ -296,6 +296,7 @@ void FFlatVertexBuffer::CreateVBO()
|
|||
{
|
||||
CreateFlatVBO();
|
||||
memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex));
|
||||
mIndex = vbo_shadowdata.Size();
|
||||
}
|
||||
else if (sectors)
|
||||
{
|
||||
|
|
|
@ -35,6 +35,7 @@ class FFlatVertexBuffer : public FVertexBuffer
|
|||
{
|
||||
FFlatVertex *map;
|
||||
unsigned int mIndex;
|
||||
unsigned int mCurIndex;
|
||||
|
||||
void CheckPlanes(sector_t *sector);
|
||||
|
||||
|
@ -49,6 +50,23 @@ public:
|
|||
void BindVBO();
|
||||
void CheckUpdate(sector_t *sector);
|
||||
|
||||
FFlatVertex *GetBuffer()
|
||||
{
|
||||
return &map[mCurIndex];
|
||||
}
|
||||
unsigned int GetCount(FFlatVertex *newptr, unsigned int *poffset)
|
||||
{
|
||||
unsigned int newofs = unsigned int(newptr - map);
|
||||
unsigned int diff = newofs - mCurIndex;
|
||||
*poffset = mCurIndex;
|
||||
mCurIndex = newofs;
|
||||
return diff;
|
||||
}
|
||||
void Reset()
|
||||
{
|
||||
mCurIndex = mIndex;
|
||||
}
|
||||
|
||||
private:
|
||||
int CreateSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor);
|
||||
int CreateSectorVertices(sector_t *sec, const secplane_t &plane, int floor);
|
||||
|
|
|
@ -238,21 +238,72 @@ bool GLFlat::SetupSubsectorLights(bool lightsapplied, subsector_t * sub)
|
|||
|
||||
void GLFlat::DrawSubsector(subsector_t * sub)
|
||||
{
|
||||
if (!gl_usevbo)
|
||||
{
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
|
||||
for(unsigned int k=0; k<sub->numlines; k++)
|
||||
if (plane.plane.a | plane.plane.b)
|
||||
{
|
||||
for (unsigned int k = 0; k < sub->numlines; k++)
|
||||
{
|
||||
vertex_t *vt = sub->firstline[k].v1;
|
||||
glTexCoord2f(vt->fx/64.f, -vt->fy/64.f);
|
||||
glTexCoord2f(vt->fx / 64.f, -vt->fy / 64.f);
|
||||
float zc = plane.plane.ZatPoint(vt->fx, vt->fy) + dz;
|
||||
glVertex3f(vt->fx, zc, vt->fy);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float zc = FIXED2FLOAT(plane.plane.Zat0()) + dz;
|
||||
for (unsigned int k = 0; k < sub->numlines; k++)
|
||||
{
|
||||
vertex_t *vt = sub->firstline[k].v1;
|
||||
glTexCoord2f(vt->fx / 64.f, -vt->fy / 64.f);
|
||||
glVertex3f(vt->fx, zc, vt->fy);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
if (plane.plane.a | plane.plane.b)
|
||||
{
|
||||
for (unsigned int k = 0; k < sub->numlines; k++)
|
||||
{
|
||||
vertex_t *vt = sub->firstline[k].v1;
|
||||
ptr->x = vt->fx;
|
||||
ptr->y = vt->fy;
|
||||
ptr->z = plane.plane.ZatPoint(vt->fx, vt->fy) + dz;
|
||||
ptr->u = vt->fx / 64.f;
|
||||
ptr->v = -vt->fy / 64.f;
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float zc = FIXED2FLOAT(plane.plane.Zat0()) + dz;
|
||||
for (unsigned int k = 0; k < sub->numlines; k++)
|
||||
{
|
||||
vertex_t *vt = sub->firstline[k].v1;
|
||||
ptr->x = vt->fx;
|
||||
ptr->y = vt->fy;
|
||||
ptr->z = zc;
|
||||
ptr->u = vt->fx / 64.f;
|
||||
ptr->v = -vt->fy / 64.f;
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
unsigned int offset;
|
||||
unsigned int count = GLRenderer->mVBO->GetCount(ptr, &offset);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, offset, count);
|
||||
}
|
||||
|
||||
flatvertices += sub->numlines;
|
||||
flatprimitives++;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -292,7 +343,6 @@ void GLFlat::DrawSubsectors(int pass, bool istrans)
|
|||
}
|
||||
else
|
||||
{
|
||||
//glColor3f( .5f,1.f,.5f); // these are for testing the VBO stuff.
|
||||
// Draw the subsectors belonging to this sector
|
||||
for (int i=0; i<sector->subsectorcount; i++)
|
||||
{
|
||||
|
|
|
@ -931,6 +931,7 @@ void FGLRenderer::RenderView (player_t* player)
|
|||
}
|
||||
|
||||
gl_RenderState.SetVertexBuffer(mVBO);
|
||||
GLRenderer->mVBO->Reset();
|
||||
|
||||
// reset statistics counters
|
||||
ResetProfilingData();
|
||||
|
@ -991,6 +992,8 @@ void FGLRenderer::WriteSavePic (player_t *player, FILE *file, int width, int hei
|
|||
bounds.height=height;
|
||||
glFlush();
|
||||
SetFixedColormap(player);
|
||||
gl_RenderState.SetVertexBuffer(mVBO);
|
||||
GLRenderer->mVBO->Reset();
|
||||
|
||||
// Check if there's some lights. If not some code can be skipped.
|
||||
TThinkerIterator<ADynamicLight> it(STAT_DLIGHT);
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/renderer/gl_lightdata.h"
|
||||
#include "gl/data/gl_data.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "gl/dynlights/gl_glow.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
#include "gl/scene/gl_portal.h"
|
||||
|
@ -88,6 +89,37 @@ void GLWall::SplitUpperEdge(texcoord * tcs)
|
|||
vertexcount += sidedef->numsegs-1;
|
||||
}
|
||||
|
||||
void GLWall::SplitUpperEdge(texcoord * tcs, FFlatVertex *&ptr)
|
||||
{
|
||||
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[2].u - tcs[1].u) / polyw;
|
||||
float facv = (tcs[2].v - tcs[1].v) / polyw;
|
||||
float fact = (ztop[1] - ztop[0]) / polyw;
|
||||
float facc = (zceil[1] - zceil[0]) / polyw;
|
||||
float facf = (zfloor[1] - zfloor[0]) / polyw;
|
||||
|
||||
for (int i = 0; i < sidedef->numsegs - 1; i++)
|
||||
{
|
||||
seg_t *cseg = sidedef->segs[i];
|
||||
float sidefrac = cseg->sidefrac;
|
||||
if (sidefrac <= glseg.fracleft) continue;
|
||||
if (sidefrac >= glseg.fracright) return;
|
||||
|
||||
float fracfac = sidefrac - glseg.fracleft;
|
||||
|
||||
ptr->x = cseg->v2->fx;
|
||||
ptr->y = cseg->v2->fy;
|
||||
ptr->z = ztop[0] + fact * fracfac;
|
||||
ptr->u = tcs[1].u + facu * fracfac;
|
||||
ptr->v = tcs[1].v + facv * fracfac;
|
||||
ptr++;
|
||||
}
|
||||
vertexcount += sidedef->numsegs - 1;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Split upper edge of wall
|
||||
|
@ -121,6 +153,37 @@ void GLWall::SplitLowerEdge(texcoord * tcs)
|
|||
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;
|
||||
|
||||
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;
|
||||
|
||||
ptr->x = cseg->v2->fx;
|
||||
ptr->y = cseg->v2->fy;
|
||||
ptr->z = zbottom[0] + facb * fracfac;
|
||||
ptr->u = tcs[0].u + facu * fracfac;
|
||||
ptr->v = tcs[0].v + facv * fracfac;
|
||||
ptr++;
|
||||
}
|
||||
vertexcount += sidedef->numsegs - 1;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Split left edge of wall
|
||||
|
@ -153,6 +216,35 @@ void GLWall::SplitLeftEdge(texcoord * tcs)
|
|||
}
|
||||
}
|
||||
|
||||
void GLWall::SplitLeftEdge(texcoord * tcs, FFlatVertex *&ptr)
|
||||
{
|
||||
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 (i<vi->numheights && vi->heightlist[i] <= zbottom[0]) i++;
|
||||
while (i<vi->numheights && vi->heightlist[i] < ztop[0])
|
||||
{
|
||||
ptr->x = glseg.x1;
|
||||
ptr->y = glseg.y1;
|
||||
ptr->z = vi->heightlist[i];
|
||||
ptr->u = factu1*(vi->heightlist[i] - ztop[0]) + tcs[1].u;
|
||||
ptr->v = factv1*(vi->heightlist[i] - ztop[0]) + tcs[1].v;
|
||||
ptr++;
|
||||
i++;
|
||||
}
|
||||
vertexcount += i;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Split right edge of wall
|
||||
|
@ -185,3 +277,32 @@ void GLWall::SplitRightEdge(texcoord * tcs)
|
|||
}
|
||||
}
|
||||
|
||||
void GLWall::SplitRightEdge(texcoord * tcs, FFlatVertex *&ptr)
|
||||
{
|
||||
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])
|
||||
{
|
||||
ptr->x = glseg.x2;
|
||||
ptr->y = glseg.y2;
|
||||
ptr->z = vi->heightlist[i];
|
||||
ptr->u = factu2*(vi->heightlist[i] - ztop[1]) + tcs[2].u;
|
||||
ptr->v = factv2*(vi->heightlist[i] - ztop[1]) + tcs[2].v;
|
||||
ptr++;
|
||||
i--;
|
||||
}
|
||||
vertexcount += i;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ struct GLDrawList;
|
|||
struct GLSkyInfo;
|
||||
struct FTexCoordInfo;
|
||||
struct FPortal;
|
||||
struct FFlatVertex;
|
||||
|
||||
|
||||
enum WallTypes
|
||||
|
@ -215,6 +216,11 @@ private:
|
|||
void SplitUpperEdge(texcoord * tcs);
|
||||
void SplitLowerEdge(texcoord * tcs);
|
||||
|
||||
void SplitLeftEdge(texcoord * tcs, FFlatVertex *&ptr);
|
||||
void SplitRightEdge(texcoord * tcs, FFlatVertex *&ptr);
|
||||
void SplitUpperEdge(texcoord * tcs, FFlatVertex *&ptr);
|
||||
void SplitLowerEdge(texcoord * tcs, FFlatVertex *&ptr);
|
||||
|
||||
public:
|
||||
|
||||
void Process(seg_t *seg, sector_t *frontsector, sector_t *backsector);
|
||||
|
|
|
@ -48,7 +48,9 @@
|
|||
#include "gl/system/gl_cvars.h"
|
||||
#include "gl/renderer/gl_lightdata.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/data/gl_data.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "gl/dynlights/gl_dynlight.h"
|
||||
#include "gl/dynlights/gl_glow.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
|
@ -248,17 +250,20 @@ void GLWall::RenderWall(int textured, float * color2, ADynamicLight * light)
|
|||
|
||||
// the rest of the code is identical for textured rendering and lights
|
||||
|
||||
|
||||
if (!gl_usevbo)
|
||||
{
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
|
||||
// lower left corner
|
||||
if (textured&1) glTexCoord2f(tcs[0].u,tcs[0].v);
|
||||
glVertex3f(glseg.x1,zbottom[0],glseg.y1);
|
||||
if (textured & 1) glTexCoord2f(tcs[0].u, tcs[0].v);
|
||||
glVertex3f(glseg.x1, zbottom[0], glseg.y1);
|
||||
|
||||
if (split && glseg.fracleft==0) SplitLeftEdge(tcs);
|
||||
if (split && glseg.fracleft == 0) SplitLeftEdge(tcs);
|
||||
|
||||
// upper left corner
|
||||
if (textured&1) glTexCoord2f(tcs[1].u,tcs[1].v);
|
||||
glVertex3f(glseg.x1,ztop[0],glseg.y1);
|
||||
if (textured & 1) glTexCoord2f(tcs[1].u, tcs[1].v);
|
||||
glVertex3f(glseg.x1, ztop[0], glseg.y1);
|
||||
|
||||
if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs);
|
||||
|
||||
|
@ -266,20 +271,59 @@ void GLWall::RenderWall(int textured, float * color2, ADynamicLight * light)
|
|||
if (color2) glColor4fv(color2);
|
||||
|
||||
// upper right corner
|
||||
if (textured&1) glTexCoord2f(tcs[2].u,tcs[2].v);
|
||||
glVertex3f(glseg.x2,ztop[1],glseg.y2);
|
||||
if (textured & 1) glTexCoord2f(tcs[2].u, tcs[2].v);
|
||||
glVertex3f(glseg.x2, ztop[1], glseg.y2);
|
||||
|
||||
if (split && glseg.fracright==1) SplitRightEdge(tcs);
|
||||
if (split && glseg.fracright == 1) SplitRightEdge(tcs);
|
||||
|
||||
// lower right corner
|
||||
if (textured&1) glTexCoord2f(tcs[3].u,tcs[3].v);
|
||||
glVertex3f(glseg.x2,zbottom[1],glseg.y2);
|
||||
if (textured & 1) glTexCoord2f(tcs[3].u, tcs[3].v);
|
||||
glVertex3f(glseg.x2, zbottom[1], glseg.y2);
|
||||
|
||||
if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs);
|
||||
|
||||
glEnd();
|
||||
|
||||
vertexcount+=4;
|
||||
vertexcount += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
|
||||
ptr->x = glseg.x1;
|
||||
ptr->y = glseg.y1;
|
||||
ptr->z = zbottom[0];
|
||||
ptr->u = tcs[0].u;
|
||||
ptr->v = tcs[0].v;
|
||||
ptr++;
|
||||
if (split && glseg.fracleft == 0) SplitLeftEdge(tcs, ptr);
|
||||
ptr->x = glseg.x1;
|
||||
ptr->y = glseg.y1;
|
||||
ptr->z = ztop[0];
|
||||
ptr->u = tcs[1].u;
|
||||
ptr->v = tcs[1].v;
|
||||
ptr++;
|
||||
if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs, ptr);
|
||||
ptr->x = glseg.x2;
|
||||
ptr->y = glseg.y2;
|
||||
ptr->z = ztop[1];
|
||||
ptr->u = tcs[2].u;
|
||||
ptr->v = tcs[2].v;
|
||||
ptr++;
|
||||
if (split && glseg.fracright == 1) SplitRightEdge(tcs, ptr);
|
||||
ptr->x = glseg.x2;
|
||||
ptr->y = glseg.y2;
|
||||
ptr->z = zbottom[1];
|
||||
ptr->u = tcs[3].u;
|
||||
ptr->v = tcs[3].v;
|
||||
ptr++;
|
||||
if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs, ptr);
|
||||
unsigned int offset;
|
||||
unsigned int count = GLRenderer->mVBO->GetCount(ptr, &offset);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, offset, count);
|
||||
vertexcount += 4;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue