- use client arrays on compatibility profiles instead of calling glBegin/glEnd.

This eliminates most behavioral differences for FFlatVertexBuffer between both operating modes, now the only difference is where the buffer is located.
This commit is contained in:
Christoph Oelckers 2016-08-06 12:03:16 +02:00
parent 346badf25f
commit 2e555e6dab
4 changed files with 46 additions and 42 deletions

View File

@ -78,9 +78,9 @@ FVertexBuffer::~FVertexBuffer()
//========================================================================== //==========================================================================
FFlatVertexBuffer::FFlatVertexBuffer() FFlatVertexBuffer::FFlatVertexBuffer()
: FVertexBuffer(!!(gl.flags & RFL_BUFFER_STORAGE)) : FVertexBuffer(gl.buffermethod == BM_PERSISTENT)
{ {
if (gl.flags & RFL_BUFFER_STORAGE) if (gl.buffermethod == BM_PERSISTENT)
{ {
unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex); unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id); glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
@ -91,19 +91,24 @@ FFlatVertexBuffer::FFlatVertexBuffer()
{ {
// The fallback path uses immediate mode rendering and does not set up an actual vertex buffer // The fallback path uses immediate mode rendering and does not set up an actual vertex buffer
vbo_shadowdata.Reserve(BUFFER_SIZE); vbo_shadowdata.Reserve(BUFFER_SIZE);
map = &vbo_shadowdata[0]; map = new FFlatVertex[BUFFER_SIZE];
} }
mNumReserved = mIndex = mCurIndex = 0; mNumReserved = mIndex = mCurIndex = 0;
} }
FFlatVertexBuffer::~FFlatVertexBuffer() FFlatVertexBuffer::~FFlatVertexBuffer()
{ {
if (gl.flags & RFL_BUFFER_STORAGE) if (vbo_id != 0)
{ {
glBindBuffer(GL_ARRAY_BUFFER, vbo_id); glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
glUnmapBuffer(GL_ARRAY_BUFFER); glUnmapBuffer(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
} }
else
{
delete[] map;
}
map = nullptr;
} }
@ -116,14 +121,15 @@ void FFlatVertexBuffer::BindVBO()
{ {
glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->x); glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->x);
glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->u); glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->u);
glEnableVertexAttribArray(VATTR_VERTEX);
glEnableVertexAttribArray(VATTR_TEXCOORD);
} }
else else
{ {
glDisableVertexAttribArray(VATTR_VERTEX); // If we cannot use a hardware buffer, use an old-style client array.
glDisableVertexAttribArray(VATTR_TEXCOORD); glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FFlatVertex), &map->x);
glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FFlatVertex), &map->u);
} }
glEnableVertexAttribArray(VATTR_VERTEX);
glEnableVertexAttribArray(VATTR_TEXCOORD);
glDisableVertexAttribArray(VATTR_COLOR); glDisableVertexAttribArray(VATTR_COLOR);
glDisableVertexAttribArray(VATTR_VERTEX2); glDisableVertexAttribArray(VATTR_VERTEX2);
} }
@ -346,24 +352,10 @@ void FFlatVertexBuffer::UpdatePlaneVertices(sector_t *sec, int plane)
void FFlatVertexBuffer::CreateVBO() void FFlatVertexBuffer::CreateVBO()
{ {
if (gl.flags & RFL_BUFFER_STORAGE)
{
vbo_shadowdata.Resize(mNumReserved); vbo_shadowdata.Resize(mNumReserved);
CreateFlatVBO(); CreateFlatVBO();
mCurIndex = mIndex = vbo_shadowdata.Size(); mCurIndex = mIndex = vbo_shadowdata.Size();
memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex)); memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex));
}
else if (sectors)
{
// set all VBO info to invalid values so that we can save some checks in the rendering code
for(int i=0;i<numsectors;i++)
{
sectors[i].vboindex[3] = sectors[i].vboindex[2] =
sectors[i].vboindex[1] = sectors[i].vboindex[0] = -1;
sectors[i].vboheight[1] = sectors[i].vboheight[0] = FLT_MIN;
}
}
} }
//========================================================================== //==========================================================================
@ -395,12 +387,9 @@ void FFlatVertexBuffer::CheckPlanes(sector_t *sector)
void FFlatVertexBuffer::CheckUpdate(sector_t *sector) void FFlatVertexBuffer::CheckUpdate(sector_t *sector)
{ {
if (gl.flags & RFL_BUFFER_STORAGE)
{
CheckPlanes(sector); CheckPlanes(sector);
sector_t *hs = sector->GetHeightSec(); sector_t *hs = sector->GetHeightSec();
if (hs != NULL) CheckPlanes(hs); if (hs != NULL) CheckPlanes(hs);
for (unsigned i = 0; i < sector->e->XFloor.ffloors.Size(); i++) for (unsigned i = 0; i < sector->e->XFloor.ffloors.Size(); i++)
CheckPlanes(sector->e->XFloor.ffloors[i]->model); CheckPlanes(sector->e->XFloor.ffloors[i]->model);
}
} }

View File

@ -85,14 +85,7 @@ public:
void RenderArray(unsigned int primtype, unsigned int offset, unsigned int count) void RenderArray(unsigned int primtype, unsigned int offset, unsigned int count)
{ {
drawcalls.Clock(); drawcalls.Clock();
if (gl.flags & RFL_BUFFER_STORAGE)
{
glDrawArrays(primtype, offset, count); glDrawArrays(primtype, offset, count);
}
else
{
ImmRenderBuffer(primtype, offset, count);
}
drawcalls.Unclock(); drawcalls.Unclock();
} }

View File

@ -167,6 +167,7 @@ void gl_LoadExtensions()
gl.vendorstring = (char*)glGetString(GL_VENDOR); gl.vendorstring = (char*)glGetString(GL_VENDOR);
gl.lightmethod = LM_SOFTWARE; gl.lightmethod = LM_SOFTWARE;
gl.buffermethod = BM_CLIENTARRAY;
if ((gl.version >= 3.3f || CheckExtension("GL_ARB_sampler_objects")) && !Args->CheckParm("-nosampler")) if ((gl.version >= 3.3f || CheckExtension("GL_ARB_sampler_objects")) && !Args->CheckParm("-nosampler"))
{ {
@ -177,6 +178,10 @@ void gl_LoadExtensions()
if (gl.version > 3.0f && (gl.version >= 3.3f || CheckExtension("GL_ARB_uniform_buffer_object"))) if (gl.version > 3.0f && (gl.version >= 3.3f || CheckExtension("GL_ARB_uniform_buffer_object")))
{ {
gl.lightmethod = LM_DEFERRED; gl.lightmethod = LM_DEFERRED;
// Only Apple requires the core profile for GL 3.x+.
// #ifdef __APPLE__
// gl.buffermethod = BM_DEFERRED;
// #endif
} }
if (CheckExtension("GL_ARB_texture_compression")) gl.flags |= RFL_TEXTURE_COMPRESSION; if (CheckExtension("GL_ARB_texture_compression")) gl.flags |= RFL_TEXTURE_COMPRESSION;
@ -222,6 +227,7 @@ void gl_LoadExtensions()
} }
gl.flags |= RFL_BUFFER_STORAGE; gl.flags |= RFL_BUFFER_STORAGE;
gl.lightmethod = LM_DIRECT; gl.lightmethod = LM_DIRECT;
gl.buffermethod = BM_PERSISTENT;
} }
else else
{ {
@ -236,6 +242,13 @@ void gl_LoadExtensions()
if (!stricmp(lm, "textured")) gl.lightmethod = LM_SOFTWARE; if (!stricmp(lm, "textured")) gl.lightmethod = LM_SOFTWARE;
} }
lm = Args->CheckValue("-buffermethod");
if (lm != NULL)
{
//if (!stricmp(lm, "deferred") && gl.buffermethod == BM_PERSISTENT) gl.buffermethod = BM_DEFERRED;
if (!stricmp(lm, "clientarray")) gl.buffermethod = BM_CLIENTARRAY;
}
int v; int v;
if (gl.lightmethod != LM_SOFTWARE && !(gl.flags & RFL_SHADER_STORAGE_BUFFER)) if (gl.lightmethod != LM_SOFTWARE && !(gl.flags & RFL_SHADER_STORAGE_BUFFER))

View File

@ -44,6 +44,14 @@ enum ELightMethod
LM_DIRECT = 2, // calculate lights on the fly along with the render data LM_DIRECT = 2, // calculate lights on the fly along with the render data
}; };
enum EBufferMethod
{
BM_CLIENTARRAY = 0, // use a client array instead of a hardware buffer
BM_DEFERRED = 1, // use a temporarily mapped buffer (only necessary on GL 3.x core profile, i.e. Apple)
BM_PERSISTENT = 2 // use a persistently mapped buffer
};
struct RenderContext struct RenderContext
{ {
unsigned int flags; unsigned int flags;
@ -51,6 +59,7 @@ struct RenderContext
unsigned int maxuniformblock; unsigned int maxuniformblock;
unsigned int uniformblockalignment; unsigned int uniformblockalignment;
int lightmethod; int lightmethod;
int buffermethod;
float version; float version;
float glslversion; float glslversion;
int max_texturesize; int max_texturesize;