- use a software buffer for immediate mode rendering. This allows using the regular buffer code to collect data for both render modes and allows removal of a lot of duplicated code.

This commit is contained in:
Christoph Oelckers 2014-06-15 01:14:41 +02:00
parent 5b302ed3a6
commit 3644073bbd
12 changed files with 232 additions and 636 deletions

View file

@ -53,7 +53,7 @@ CUSTOM_CVAR(Int, gl_usevbo, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCA
{
if (self < -1 || self > 1 || !(gl.flags & RFL_BUFFER_STORAGE))
{
self = 0;
if (self != 0) self = 0;
}
else if (self == -1)
{
@ -101,7 +101,8 @@ FFlatVertexBuffer::FFlatVertexBuffer()
}
else
{
map = NULL;
vbo_shadowdata.Reserve(BUFFER_SIZE);
map = &vbo_shadowdata[0];
}
mIndex = mCurIndex = 0;
}
@ -113,6 +114,25 @@ FFlatVertexBuffer::~FFlatVertexBuffer()
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
//==========================================================================
//
// Renders the buffer's contents with immediate mode functions
// This is here so that the immediate mode fallback does not need
// to double all rendering code and can instead reuse the buffer-based version
//
//==========================================================================
void FFlatVertexBuffer::ImmRenderBuffer(unsigned int primtype, unsigned int offset, unsigned int count)
{
glBegin(primtype);
for (unsigned int i = 0; i < count; i++)
{
glTexCoord2fv(&map[offset + i].u);
glVertex3fv(&map[offset + i].x);
}
glEnd();
}
//==========================================================================
//
// Initialize a single vertex
@ -369,7 +389,7 @@ void FFlatVertexBuffer::CheckPlanes(sector_t *sector)
void FFlatVertexBuffer::CheckUpdate(sector_t *sector)
{
if (vbo_arg == 2)
if (gl.flags & RFL_BUFFER_STORAGE)
{
CheckPlanes(sector);
sector_t *hs = sector->GetHeightSec();

View file

@ -3,6 +3,7 @@
#include "tarray.h"
#include "gl/utility/gl_clock.h"
#include "gl/system/gl_interface.h"
struct vertex_t;
struct secplane_t;
@ -43,6 +44,7 @@ struct FFlatVertex
class FFlatVertexBuffer : public FVertexBuffer
{
FFlatVertex *map;
FFlatVertex mDrawBuffer[1000];
unsigned int mIndex;
unsigned int mCurIndex;
@ -50,9 +52,10 @@ class FFlatVertexBuffer : public FVertexBuffer
const unsigned int BUFFER_SIZE = 2000000;
void ImmRenderBuffer(unsigned int primtype, unsigned int offset, unsigned int count);
public:
int vbo_arg;
TArray<FFlatVertex> vbo_shadowdata; // this is kept around for updating the actual (non-readable) buffer
TArray<FFlatVertex> vbo_shadowdata; // this is kept around for updating the actual (non-readable) buffer and as stand-in for pre GL 4.x
FFlatVertexBuffer();
~FFlatVertexBuffer();
@ -67,6 +70,7 @@ public:
}
unsigned int GetCount(FFlatVertex *newptr, unsigned int *poffset)
{
unsigned int newofs = (unsigned int)(newptr - map);
unsigned int diff = newofs - mCurIndex;
*poffset = mCurIndex;
@ -75,16 +79,29 @@ public:
return diff;
}
#ifdef __GL_PCH_H // we need the system includes for this but we cannot include them ourselves without creating #define clashes. The affected files wouldn't try to draw anyway.
void RenderArray(unsigned int primtype, unsigned int offset, unsigned int count)
{
drawcalls.Clock();
if (gl.flags & RFL_BUFFER_STORAGE)
{
glDrawArrays(primtype, offset, count);
}
else
{
ImmRenderBuffer(primtype, offset, count);
}
drawcalls.Unclock();
}
void RenderCurrent(FFlatVertex *newptr, unsigned int primtype, unsigned int *poffset = NULL, unsigned int *pcount = NULL)
{
unsigned int offset;
unsigned int count = GetCount(newptr, &offset);
drawcalls.Clock();
glDrawArrays(primtype, offset, count);
drawcalls.Unclock();
RenderArray(primtype, offset, count);
if (poffset) *poffset = offset;
if (pcount) *pcount = count;
}
#endif
void Reset()
{

View file

@ -283,36 +283,17 @@ void FGLRenderer::ClearBorders()
gl_RenderState.EnableTexture(false);
gl_RenderState.Apply();
if (!gl_usevbo)
{
glBegin(GL_QUADS);
// upper quad
glVertex2i(0, borderHeight);
glVertex2i(0, 0);
glVertex2i(width, 0);
glVertex2i(width, borderHeight);
// lower quad
glVertex2i(0, trueHeight);
glVertex2i(0, trueHeight - borderHeight);
glVertex2i(width, trueHeight - borderHeight);
glVertex2i(width, trueHeight);
glEnd();
}
else
{
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(0, borderHeight, 0, 0, 0); ptr++;
ptr->Set(0, 0, 0, 0, 0); ptr++;
ptr->Set(width, 0, 0, 0, 0); ptr++;
ptr->Set(width, borderHeight, 0, 0, 0); ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
ptr->Set(0, trueHeight, 0, 0, 0); ptr++;
ptr->Set(0, trueHeight - borderHeight, 0, 0, 0); ptr++;
ptr->Set(width, trueHeight - borderHeight, 0, 0, 0); ptr++;
ptr->Set(width, trueHeight, 0, 0, 0); ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
}
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(0, borderHeight, 0, 0, 0); ptr++;
ptr->Set(0, 0, 0, 0, 0); ptr++;
ptr->Set(width, 0, 0, 0, 0); ptr++;
ptr->Set(width, borderHeight, 0, 0, 0); ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
ptr->Set(0, trueHeight, 0, 0, 0); ptr++;
ptr->Set(0, trueHeight - borderHeight, 0, 0, 0); ptr++;
ptr->Set(width, trueHeight - borderHeight, 0, 0, 0); ptr++;
ptr->Set(width, trueHeight, 0, 0, 0); ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
gl_RenderState.EnableTexture(true);
glViewport(0, (trueHeight - height) / 2, width, height);
@ -412,28 +393,13 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms)
gl_RenderState.SetColor(color);
gl_RenderState.EnableAlphaTest(false);
gl_RenderState.Apply();
if (!gl_usevbo)
{
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(u1, v1);
glVertex2d(x, y);
glTexCoord2f(u1, v2);
glVertex2d(x, y + h);
glTexCoord2f(u2, v1);
glVertex2d(x + w, y);
glTexCoord2f(u2, v2);
glVertex2d(x + w, y + h);
glEnd();
}
else
{
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(x, y, 0, u1, v1); ptr++;
ptr->Set(x, y + h, 0, u1, v2); ptr++;
ptr->Set(x + w, y, 0, u2, v1); ptr++;
ptr->Set(x + w, y + h, 0, u2, v2); ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
}
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(x, y, 0, u1, v1); ptr++;
ptr->Set(x, y + h, 0, u1, v2); ptr++;
ptr->Set(x + w, y, 0, u2, v1); ptr++;
ptr->Set(x + w, y + h, 0, u2, v2); ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
if (parms.colorOverlay)
{
@ -443,28 +409,12 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms)
gl_RenderState.SetColor(PalEntry(parms.colorOverlay));
gl_RenderState.Apply();
if (!gl_usevbo)
{
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(u1, v1);
glVertex2d(x, y);
glTexCoord2f(u1, v2);
glVertex2d(x, y + h);
glTexCoord2f(u2, v1);
glVertex2d(x + w, y);
glTexCoord2f(u2, v2);
glVertex2d(x + w, y + h);
glEnd();
}
else
{
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(x, y, 0, u1, v1); ptr++;
ptr->Set(x, y + h, 0, u1, v2); ptr++;
ptr->Set(x + w, y, 0, u2, v1); ptr++;
ptr->Set(x + w, y + h, 0, u2, v2); ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
}
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(x, y, 0, u1, v1); ptr++;
ptr->Set(x, y + h, 0, u1, v2); ptr++;
ptr->Set(x + w, y, 0, u2, v1); ptr++;
ptr->Set(x + w, y + h, 0, u2, v2); ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
}
gl_RenderState.EnableAlphaTest(true);
@ -487,20 +437,12 @@ void FGLRenderer::DrawLine(int x1, int y1, int x2, int y2, int palcolor, uint32
gl_RenderState.EnableTexture(false);
gl_RenderState.SetColorAlpha(p, 1.f);
gl_RenderState.Apply();
if (!gl_usevbo)
{
glBegin(GL_LINES);
glVertex2i(x1, y1);
glVertex2i(x2, y2);
glEnd();
}
else
{
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(x1, y1, 0, 0, 0); ptr++;
ptr->Set(x2, y2, 0, 0, 0); ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_LINES);
}
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(x1, y1, 0, 0, 0); ptr++;
ptr->Set(x2, y2, 0, 0, 0); ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_LINES);
gl_RenderState.EnableTexture(true);
}
@ -515,18 +457,11 @@ void FGLRenderer::DrawPixel(int x1, int y1, int palcolor, uint32 color)
gl_RenderState.EnableTexture(false);
gl_RenderState.SetColorAlpha(p, 1.f);
gl_RenderState.Apply();
if (!gl_usevbo)
{
glBegin(GL_POINTS);
glVertex2i(x1, y1);
glEnd();
}
else
{
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(x1, y1, 0, 0, 0); ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_POINTS);
}
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(x1, y1, 0, 0, 0); ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_POINTS);
gl_RenderState.EnableTexture(true);
}
@ -544,24 +479,13 @@ void FGLRenderer::Dim(PalEntry color, float damount, int x1, int y1, int w, int
gl_RenderState.SetColorAlpha(color, damount);
gl_RenderState.Apply();
if (!gl_usevbo)
{
glBegin(GL_TRIANGLE_FAN);
glVertex2i(x1, y1);
glVertex2i(x1, y1 + h);
glVertex2i(x1 + w, y1 + h);
glVertex2i(x1 + w, y1);
glEnd();
}
else
{
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(x1, y1, 0, 0, 0); ptr++;
ptr->Set(x1, y1+h, 0, 0, 0); ptr++;
ptr->Set(x1+w, y1+h, 0, 0, 0); ptr++;
ptr->Set(x1+w, y1, 0, 0, 0); ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
}
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(x1, y1, 0, 0, 0); ptr++;
ptr->Set(x1, y1+h, 0, 0, 0); ptr++;
ptr->Set(x1+w, y1+h, 0, 0, 0); ptr++;
ptr->Set(x1+w, y1, 0, 0, 0); ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
gl_RenderState.EnableTexture(true);
}
@ -597,24 +521,13 @@ void FGLRenderer::FlatFill (int left, int top, int right, int bottom, FTexture *
}
gl_RenderState.ResetColor();
gl_RenderState.Apply();
if (!gl_usevbo)
{
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(fU1, fV1); glVertex2f(left, top);
glTexCoord2f(fU1, fV2); glVertex2f(left, bottom);
glTexCoord2f(fU2, fV1); glVertex2f(right, top);
glTexCoord2f(fU2, fV2); glVertex2f(right, bottom);
glEnd();
}
else
{
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(left, top, 0, fU1, fV1); ptr++;
ptr->Set(left, bottom, 0, fU1, fV2); ptr++;
ptr->Set(right, top, 0, fU2, fV1); ptr++;
ptr->Set(right, bottom, 0, fU2, fV2); ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
}
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(left, top, 0, fU1, fV1); ptr++;
ptr->Set(left, bottom, 0, fU1, fV2); ptr++;
ptr->Set(right, top, 0, fU2, fV1); ptr++;
ptr->Set(right, bottom, 0, fU2, fV2); ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
}
//==========================================================================
@ -702,41 +615,21 @@ void FGLRenderer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoint
float oy = float(originy);
gl_RenderState.Apply();
if (!gl_usevbo)
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
for (i = 0; i < npoints; ++i)
{
glBegin(GL_TRIANGLE_FAN);
for (i = 0; i < npoints; ++i)
float u = points[i].X - 0.5f - ox;
float v = points[i].Y - 0.5f - oy;
if (dorotate)
{
float u = points[i].X - 0.5f - ox;
float v = points[i].Y - 0.5f - oy;
if (dorotate)
{
float t = u;
u = t * cosrot - v * sinrot;
v = v * cosrot + t * sinrot;
}
glTexCoord2f(u * uscale, v * vscale);
glVertex3f(points[i].X, points[i].Y /* + yoffs */, 0);
float t = u;
u = t * cosrot - v * sinrot;
v = v * cosrot + t * sinrot;
}
glEnd();
}
else
{
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
for (i = 0; i < npoints; ++i)
{
float u = points[i].X - 0.5f - ox;
float v = points[i].Y - 0.5f - oy;
if (dorotate)
{
float t = u;
u = t * cosrot - v * sinrot;
v = v * cosrot + t * sinrot;
}
ptr->Set(points[i].X, points[i].Y, 0, u*uscale, v*vscale);
ptr++;
}
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
ptr->Set(points[i].X, points[i].Y, 0, u*uscale, v*vscale);
ptr++;
}
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
}

View file

@ -337,26 +337,14 @@ void GLWall::DrawDecal(DBaseDecal *decal)
else gl_RenderState.AlphaFunc(GL_GREATER, 0.f);
gl_RenderState.Apply();
if (!gl_usevbo)
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
for (i = 0; i < 4; i++)
{
glBegin(GL_TRIANGLE_FAN);
for (i = 0; i < 4; i++)
{
glTexCoord2f(dv[i].u, dv[i].v);
glVertex3f(dv[i].x, dv[i].z, dv[i].y);
}
glEnd();
}
else
{
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
for (i = 0; i < 4; i++)
{
ptr->Set(dv[i].x, dv[i].z, dv[i].y, dv[i].u, dv[i].v);
ptr++;
}
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
ptr->Set(dv[i].x, dv[i].z, dv[i].y, dv[i].u, dv[i].v);
ptr++;
}
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
rendered_decals++;
gl_RenderState.SetTextureMode(TM_MODULATE);
gl_RenderState.SetObjectColor(0xffffffff);

View file

@ -991,28 +991,17 @@ void FDrawInfo::SetupFloodStencil(wallseg * ws)
glDepthMask(true);
gl_RenderState.Apply();
if (!gl_usevbo)
{
glBegin(GL_TRIANGLE_FAN);
glVertex3f(ws->x1, ws->z1, ws->y1);
glVertex3f(ws->x1, ws->z2, ws->y1);
glVertex3f(ws->x2, ws->z2, ws->y2);
glVertex3f(ws->x2, ws->z1, ws->y2);
glEnd();
}
else
{
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(ws->x1, ws->z1, ws->y1, 0, 0);
ptr++;
ptr->Set(ws->x1, ws->z2, ws->y1, 0, 0);
ptr++;
ptr->Set(ws->x2, ws->z2, ws->y2, 0, 0);
ptr++;
ptr->Set(ws->x2, ws->z1, ws->y2, 0, 0);
ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
}
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(ws->x1, ws->z1, ws->y1, 0, 0);
ptr++;
ptr->Set(ws->x1, ws->z2, ws->y1, 0, 0);
ptr++;
ptr->Set(ws->x2, ws->z2, ws->y2, 0, 0);
ptr++;
ptr->Set(ws->x2, ws->z1, ws->y2, 0, 0);
ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
glStencilFunc(GL_EQUAL,recursion+1,~0); // draw sky into stencil
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); // this stage doesn't modify the stencil
@ -1033,28 +1022,16 @@ void FDrawInfo::ClearFloodStencil(wallseg * ws)
gl_RenderState.ResetColor();
gl_RenderState.Apply();
if (!gl_usevbo)
{
glBegin(GL_TRIANGLE_FAN);
glVertex3f(ws->x1, ws->z1, ws->y1);
glVertex3f(ws->x1, ws->z2, ws->y1);
glVertex3f(ws->x2, ws->z2, ws->y2);
glVertex3f(ws->x2, ws->z1, ws->y2);
glEnd();
}
else
{
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(ws->x1, ws->z1, ws->y1, 0, 0);
ptr++;
ptr->Set(ws->x1, ws->z2, ws->y1, 0, 0);
ptr++;
ptr->Set(ws->x2, ws->z2, ws->y2, 0, 0);
ptr++;
ptr->Set(ws->x2, ws->z1, ws->y2, 0, 0);
ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
}
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(ws->x1, ws->z1, ws->y1, 0, 0);
ptr++;
ptr->Set(ws->x1, ws->z2, ws->y1, 0, 0);
ptr++;
ptr->Set(ws->x2, ws->z2, ws->y2, 0, 0);
ptr++;
ptr->Set(ws->x2, ws->z1, ws->y2, 0, 0);
ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
// restore old stencil op.
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
@ -1126,36 +1103,16 @@ void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, boo
float px4 = fviewx + prj_fac1 * (ws->x2-fviewx);
float py4 = fviewy + prj_fac1 * (ws->y2-fviewy);
if (!gl_usevbo)
{
glBegin(GL_TRIANGLE_FAN);
glTexCoord2f(px1 / 64, -py1 / 64);
glVertex3f(px1, planez, py1);
glTexCoord2f(px2 / 64, -py2 / 64);
glVertex3f(px2, planez, py2);
glTexCoord2f(px3 / 64, -py3 / 64);
glVertex3f(px3, planez, py3);
glTexCoord2f(px4 / 64, -py4 / 64);
glVertex3f(px4, planez, py4);
glEnd();
}
else
{
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(px1, planez, py1, px1 / 64, -py1 / 64);
ptr++;
ptr->Set(px2, planez, py2, px2 / 64, -py2 / 64);
ptr++;
ptr->Set(px3, planez, py3, px3 / 64, -py3 / 64);
ptr++;
ptr->Set(px4, planez, py4, px4 / 64, -py4 / 64);
ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
}
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(px1, planez, py1, px1 / 64, -py1 / 64);
ptr++;
ptr->Set(px2, planez, py2, px2 / 64, -py2 / 64);
ptr++;
ptr->Set(px3, planez, py3, px3 / 64, -py3 / 64);
ptr++;
ptr->Set(px4, planez, py4, px4 / 64, -py4 / 64);
ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
if (pushed)
{

View file

@ -239,64 +239,35 @@ bool GLFlat::SetupSubsectorLights(bool lightsapplied, subsector_t * sub)
void GLFlat::DrawSubsector(subsector_t * sub)
{
if (!gl_usevbo)
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
if (plane.plane.a | plane.plane.b)
{
glBegin(GL_TRIANGLE_FAN);
if (plane.plane.a | plane.plane.b)
for (unsigned int k = 0; k < sub->numlines; k++)
{
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);
float zc = plane.plane.ZatPoint(vt->fx, vt->fy) + dz;
glVertex3f(vt->fx, zc, vt->fy);
}
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;
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)
float zc = FIXED2FLOAT(plane.plane.Zat0()) + dz;
for (unsigned int k = 0; k < sub->numlines; k++)
{
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++;
}
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++;
}
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++;
}
}
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
}
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
flatvertices += sub->numlines;
flatprimitives++;
@ -332,9 +303,9 @@ void GLFlat::DrawSubsectors(int pass, bool istrans)
if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans)
{
if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, sub);
drawcalls.Clock();
//drawcalls.Clock();
glDrawArrays(GL_TRIANGLE_FAN, index, sub->numlines);
drawcalls.Unclock();
//drawcalls.Unclock();
flatvertices += sub->numlines;
flatprimitives++;
}

View file

@ -617,28 +617,16 @@ static void FillScreen()
gl_RenderState.EnableAlphaTest(false);
gl_RenderState.EnableTexture(false);
gl_RenderState.Apply();
if (!gl_usevbo)
{
glBegin(GL_TRIANGLE_STRIP);
glVertex2f(0.0f, 0.0f);
glVertex2f(0.0f, (float)SCREENHEIGHT);
glVertex2f((float)SCREENWIDTH, 0.0f);
glVertex2f((float)SCREENWIDTH, (float)SCREENHEIGHT);
glEnd();
}
else
{
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(0, 0, 0, 0, 0);
ptr++;
ptr->Set(0, (float)SCREENHEIGHT, 0, 0, 0);
ptr++;
ptr->Set((float)SCREENWIDTH, 0, 0, 0, 0);
ptr++;
ptr->Set((float)SCREENWIDTH, (float)SCREENHEIGHT, 0, 0, 0);
ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
}
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(0, 0, 0, 0, 0);
ptr++;
ptr->Set(0, (float)SCREENHEIGHT, 0, 0, 0);
ptr++;
ptr->Set((float)SCREENWIDTH, 0, 0, 0, 0);
ptr++;
ptr->Set((float)SCREENWIDTH, (float)SCREENHEIGHT, 0, 0, 0);
ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
}
//==========================================================================

View file

@ -269,39 +269,16 @@ void GLSprite::Draw(int pass)
FFlatVertex *ptr;
unsigned int offset, count;
if (!gl_usevbo)
{
glBegin(GL_TRIANGLE_STRIP);
if (gltexture)
{
glTexCoord2f(ul, vt); glVertex3fv(&v1[0]);
glTexCoord2f(ur, vt); glVertex3fv(&v2[0]);
glTexCoord2f(ul, vb); glVertex3fv(&v3[0]);
glTexCoord2f(ur, vb); glVertex3fv(&v4[0]);
}
else // Particle
{
glVertex3fv(&v1[0]);
glVertex3fv(&v2[0]);
glVertex3fv(&v3[0]);
glVertex3fv(&v4[0]);
}
glEnd();
}
else
{
ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(v1[0], v1[1], v1[2], ul, vt);
ptr++;
ptr->Set(v2[0], v2[1], v2[2], ur, vt);
ptr++;
ptr->Set(v3[0], v3[1], v3[2], ul, vb);
ptr++;
ptr->Set(v4[0], v4[1], v4[2], ur, vb);
ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP, &offset, &count);
}
ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(v1[0], v1[1], v1[2], ul, vt);
ptr++;
ptr->Set(v2[0], v2[1], v2[2], ur, vt);
ptr++;
ptr->Set(v3[0], v3[1], v3[2], ul, vb);
ptr++;
ptr->Set(v4[0], v4[1], v4[2], ur, vb);
ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP, &offset, &count);
if (foglayer)
{
@ -311,30 +288,7 @@ void GLSprite::Draw(int pass)
gl_RenderState.BlendEquation(GL_FUNC_ADD);
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
gl_RenderState.Apply();
if (!gl_usevbo)
{
glBegin(GL_TRIANGLE_STRIP);
if (gltexture)
{
glTexCoord2f(ul, vt); glVertex3fv(&v1[0]);
glTexCoord2f(ur, vt); glVertex3fv(&v2[0]);
glTexCoord2f(ul, vb); glVertex3fv(&v3[0]);
glTexCoord2f(ur, vb); glVertex3fv(&v4[0]);
}
else // Particle
{
glVertex3fv(&v1[0]);
glVertex3fv(&v2[0]);
glVertex3fv(&v3[0]);
glVertex3fv(&v4[0]);
}
glEnd();
}
else
{
glDrawArrays(GL_TRIANGLE_STRIP, offset, count);
}
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, offset, count);
gl_RenderState.SetFixedColormap(CM_DEFAULT);
}
}

View file

@ -54,144 +54,6 @@
#include "gl/utility/gl_templates.h"
EXTERN_CVAR(Bool, gl_seamless)
extern int vertexcount;
//==========================================================================
//
// Split upper edge of wall
//
//==========================================================================
void GLWall::SplitUpperEdge(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[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;
glTexCoord2f(tcs[1].u + facu * fracfac, tcs[1].v + facv * fracfac);
glVertex3f(cseg->v2->fx, ztop[0] + fact * fracfac, cseg->v2->fy);
}
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 (i<vi->numheights && vi->heightlist[i] <= zbottom[0] ) i++;
while (i<vi->numheights && 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
//
//==========================================================================
//==========================================================================
//
@ -227,7 +89,6 @@ void GLWall::SplitUpperEdge(texcoord * tcs, FFlatVertex *&ptr)
ptr->v = tcs[1].v + facv * fracfac;
ptr++;
}
vertexcount += sidedef->numsegs - 1;
}
//==========================================================================
@ -264,7 +125,6 @@ void GLWall::SplitLowerEdge(texcoord * tcs, FFlatVertex *&ptr)
ptr->v = tcs[0].v + facv * fracfac;
ptr++;
}
vertexcount += sidedef->numsegs - 1;
}
//==========================================================================
@ -298,7 +158,6 @@ void GLWall::SplitLeftEdge(texcoord * tcs, FFlatVertex *&ptr)
ptr++;
i++;
}
vertexcount += i;
}
}
@ -333,7 +192,6 @@ void GLWall::SplitRightEdge(texcoord * tcs, FFlatVertex *&ptr)
ptr++;
i--;
}
vertexcount += i;
}
}

View file

@ -159,7 +159,7 @@ private:
void SetupLights();
bool PrepareLight(texcoord * tcs, ADynamicLight * light);
void RenderWall(int textured, float * color2, ADynamicLight * light=NULL);
void RenderWall(int textured, ADynamicLight * light=NULL);
void GetPrimitive(unsigned int *store);
void FloodPlane(int pass);
@ -212,11 +212,6 @@ private:
void RenderMirrorSurface();
void RenderTranslucentWall();
void SplitLeftEdge(texcoord * tcs);
void SplitRightEdge(texcoord * tcs);
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);

View file

@ -215,6 +215,7 @@ void GLWall::SetupLights()
}
}
//==========================================================================
//
// General purpose wall rendering function
@ -222,7 +223,7 @@ void GLWall::SetupLights()
//
//==========================================================================
void GLWall::RenderWall(int textured, float * color2, ADynamicLight * light)
void GLWall::RenderWall(int textured, ADynamicLight * light)
{
texcoord tcs[4];
bool split = (gl_seamless && !(textured&4) && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ));
@ -249,64 +250,22 @@ void GLWall::RenderWall(int textured, float * color2, ADynamicLight * light)
gl_RenderState.Apply();
// the rest of the code is identical for textured rendering and lights
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
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 (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 (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs);
// color for right side (do not set in render state!)
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 (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 (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs);
glEnd();
vertexcount += 4;
}
else
{
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[0].u, tcs[0].v);
ptr++;
if (split && glseg.fracleft == 0) SplitLeftEdge(tcs, ptr);
ptr->Set(glseg.x1, ztop[0], glseg.y1, tcs[1].u, tcs[1].v);
ptr++;
if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs, ptr);
ptr->Set(glseg.x2, ztop[1], glseg.y2, tcs[2].u, tcs[2].v);
ptr++;
if (split && glseg.fracright == 1) SplitRightEdge(tcs, ptr);
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;
}
ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[0].u, tcs[0].v);
ptr++;
if (split && glseg.fracleft == 0) SplitLeftEdge(tcs, ptr);
ptr->Set(glseg.x1, ztop[0], glseg.y1, tcs[1].u, tcs[1].v);
ptr++;
if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs, ptr);
ptr->Set(glseg.x2, ztop[1], glseg.y2, tcs[2].u, tcs[2].v);
ptr++;
if (split && glseg.fracright == 1) SplitRightEdge(tcs, ptr);
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;
}
//==========================================================================
@ -356,7 +315,7 @@ void GLWall::RenderFogBoundary()
gl_SetFog(lightlevel, rel, &Colormap, false);
gl_RenderState.SetEffect(EFF_FOGBOUNDARY);
gl_RenderState.EnableAlphaTest(false);
RenderWall(0, NULL);
RenderWall(0);
gl_RenderState.EnableAlphaTest(true);
gl_RenderState.SetEffect(EFF_NONE);
}
@ -385,8 +344,17 @@ void GLWall::RenderFogBoundary()
glDepthFunc(GL_LEQUAL);
gl_RenderState.SetColor(fc[0], fc[1], fc[2], fogd1);
flags &= ~GLWF_GLOW;
RenderWall(4,fc);
// this case is special because it needs to change the color in the middle of the polygon so it cannot use the standard function
// This also needs no splits so it's relatively simple.
gl_RenderState.Apply();
glBegin(GL_TRIANGLE_FAN);
glVertex3f(glseg.x1, zbottom[0], glseg.y1);
glVertex3f(glseg.x1, ztop[0], glseg.y1);
glColor4fv(fc);
glVertex3f(glseg.x2, ztop[1], glseg.y2);
glVertex3f(glseg.x2, zbottom[1], glseg.y2);
glEnd();
vertexcount += 4;
glDepthFunc(GL_LESS);
gl_RenderState.EnableFog(true);
@ -424,8 +392,7 @@ void GLWall::RenderMirrorSurface()
pat->BindPatch(0);
flags &= ~GLWF_GLOW;
//flags |= GLWF_NOSHADER;
RenderWall(0,NULL);
RenderWall(0);
gl_RenderState.SetEffect(EFF_NONE);
@ -486,7 +453,7 @@ void GLWall::RenderTranslucentWall()
if (type!=RENDERWALL_M2SNF) gl_SetFog(lightlevel, extra, &Colormap, isadditive);
else gl_SetFog(255, 0, NULL, false);
RenderWall(5,NULL);
RenderWall(5);
// restore default settings
if (isadditive) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -540,7 +507,7 @@ void GLWall::Draw(int pass)
gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW));
gltexture->Bind(flags, 0);
RenderWall(3, NULL);
RenderWall(3);
gl_RenderState.EnableGlow(false);
gl_RenderState.EnableLight(false);
break;
@ -561,14 +528,14 @@ void GLWall::Draw(int pass)
{
gltexture->Bind(flags, 0);
}
RenderWall(pass == GLPASS_BASE? 2:3, NULL);
RenderWall(pass == GLPASS_BASE? 2:3);
gl_RenderState.EnableGlow(false);
gl_RenderState.EnableLight(false);
break;
case GLPASS_TEXTURE: // modulated texture
gltexture->Bind(flags, 0);
RenderWall(1, NULL);
RenderWall(1);
break;
case GLPASS_LIGHT:
@ -597,7 +564,7 @@ void GLWall::Draw(int pass)
if (!(node->lightsource->flags2&MF2_DORMANT))
{
iter_dlight++;
RenderWall(1, NULL, node->lightsource);
RenderWall(1, node->lightsource);
}
node = node->nextLight;
}

View file

@ -154,28 +154,16 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed
gl_RenderState.EnableAlphaTest(false);
}
gl_RenderState.Apply();
if (!gl_usevbo)
{
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(fU1, fV1); glVertex2f(x1, y1);
glTexCoord2f(fU1, fV2); glVertex2f(x1, y2);
glTexCoord2f(fU2, fV1); glVertex2f(x2, y1);
glTexCoord2f(fU2, fV2); glVertex2f(x2, y2);
glEnd();
}
else
{
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(x1, y1, 0, fU1, fV1);
ptr++;
ptr->Set(x1, y2, 0, fU1, fV2);
ptr++;
ptr->Set(x2, y1, 0, fU2, fV1);
ptr++;
ptr->Set(x2, y2, 0, fU2, fV2);
ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
}
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(x1, y1, 0, fU1, fV1);
ptr++;
ptr->Set(x1, y2, 0, fU1, fV2);
ptr++;
ptr->Set(x2, y1, 0, fU2, fV1);
ptr++;
ptr->Set(x2, y2, 0, fU2, fV2);
ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
if (tex->GetTransparent() || OverrideShader != 0)
{
gl_RenderState.EnableAlphaTest(true);