From 2e555e6dabf18891ca82deef827fbfd427ad4373 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 6 Aug 2016 12:03:16 +0200 Subject: [PATCH] - 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. --- src/gl/data/gl_vertexbuffer.cpp | 57 +++++++++++++-------------------- src/gl/data/gl_vertexbuffer.h | 9 +----- src/gl/system/gl_interface.cpp | 13 ++++++++ src/gl/system/gl_interface.h | 9 ++++++ 4 files changed, 46 insertions(+), 42 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index 96343b284..dd3854596 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -78,9 +78,9 @@ FVertexBuffer::~FVertexBuffer() //========================================================================== 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); 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 vbo_shadowdata.Reserve(BUFFER_SIZE); - map = &vbo_shadowdata[0]; + map = new FFlatVertex[BUFFER_SIZE]; } mNumReserved = mIndex = mCurIndex = 0; } FFlatVertexBuffer::~FFlatVertexBuffer() { - if (gl.flags & RFL_BUFFER_STORAGE) + if (vbo_id != 0) { glBindBuffer(GL_ARRAY_BUFFER, vbo_id); glUnmapBuffer(GL_ARRAY_BUFFER); 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_TEXCOORD, 2, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->u); - glEnableVertexAttribArray(VATTR_VERTEX); - glEnableVertexAttribArray(VATTR_TEXCOORD); } else { - glDisableVertexAttribArray(VATTR_VERTEX); - glDisableVertexAttribArray(VATTR_TEXCOORD); + // If we cannot use a hardware buffer, use an old-style client array. + 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_VERTEX2); } @@ -346,24 +352,10 @@ void FFlatVertexBuffer::UpdatePlaneVertices(sector_t *sec, int plane) void FFlatVertexBuffer::CreateVBO() { - if (gl.flags & RFL_BUFFER_STORAGE) - { - vbo_shadowdata.Resize(mNumReserved); - CreateFlatVBO(); - mCurIndex = mIndex = vbo_shadowdata.Size(); - 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;iGetHeightSec(); - if (hs != NULL) CheckPlanes(hs); - for (unsigned i = 0; i < sector->e->XFloor.ffloors.Size(); i++) - CheckPlanes(sector->e->XFloor.ffloors[i]->model); - } + CheckPlanes(sector); + sector_t *hs = sector->GetHeightSec(); + if (hs != NULL) CheckPlanes(hs); + for (unsigned i = 0; i < sector->e->XFloor.ffloors.Size(); i++) + CheckPlanes(sector->e->XFloor.ffloors[i]->model); } \ No newline at end of file diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index 6420e8fc8..c82ea707b 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -85,14 +85,7 @@ public: 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); - } + glDrawArrays(primtype, offset, count); drawcalls.Unclock(); } diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index ced1b8b4a..beb636d9c 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -167,6 +167,7 @@ void gl_LoadExtensions() gl.vendorstring = (char*)glGetString(GL_VENDOR); gl.lightmethod = LM_SOFTWARE; + gl.buffermethod = BM_CLIENTARRAY; 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"))) { 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; @@ -222,6 +227,7 @@ void gl_LoadExtensions() } gl.flags |= RFL_BUFFER_STORAGE; gl.lightmethod = LM_DIRECT; + gl.buffermethod = BM_PERSISTENT; } else { @@ -236,6 +242,13 @@ void gl_LoadExtensions() 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; if (gl.lightmethod != LM_SOFTWARE && !(gl.flags & RFL_SHADER_STORAGE_BUFFER)) diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index 1813e2c7f..d43252ebc 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -44,6 +44,14 @@ enum ELightMethod 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 { unsigned int flags; @@ -51,6 +59,7 @@ struct RenderContext unsigned int maxuniformblock; unsigned int uniformblockalignment; int lightmethod; + int buffermethod; float version; float glslversion; int max_texturesize;