- implemented buffers for GL 3.x. These only get mapped during the data collection pass so the order of some things is different here.

This commit is contained in:
Christoph Oelckers 2016-08-29 10:43:03 +02:00
parent e0e43ee7b3
commit 0f0dc2c852
7 changed files with 74 additions and 16 deletions

View file

@ -126,6 +126,7 @@ void FSimpleVertexBuffer::EnableColorArray(bool on)
void FSimpleVertexBuffer::set(FSimpleVertex *verts, int count)
{
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
gl_RenderState.ResetVertexBuffer();
gl_RenderState.SetVertexBuffer(this);
glBufferData(GL_ARRAY_BUFFER, count * sizeof(*verts), verts, GL_STREAM_DRAW);
}
@ -139,18 +140,32 @@ void FSimpleVertexBuffer::set(FSimpleVertex *verts, int count)
FFlatVertexBuffer::FFlatVertexBuffer(int width, int height)
: FVertexBuffer(gl.buffermethod != BM_CLIENTARRAY)
{
if (gl.buffermethod != BM_CLIENTARRAY)
switch (gl.buffermethod)
{
case BM_PERSISTENT:
{
unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
glBufferStorage(GL_ARRAY_BUFFER, bytesize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
map = (FFlatVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, bytesize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
break;
}
else
case BM_DEFERRED:
{
unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
glBufferData(GL_ARRAY_BUFFER, bytesize, NULL, GL_STREAM_DRAW);
map = nullptr;
break;
}
case BM_CLIENTARRAY:
{
// The fallback path uses immediate mode rendering and does not set up an actual vertex buffer
vbo_shadowdata.Reserve(BUFFER_SIZE);
map = new FFlatVertex[BUFFER_SIZE];
break;
}
}
mIndex = mCurIndex = 0;
mNumReserved = NUM_RESERVED;
@ -185,6 +200,13 @@ FFlatVertexBuffer::FFlatVertexBuffer(int width, int height)
vbo_shadowdata[18].Set(32767.0f, -32767.0f, 32767.0f, 0, 0);
vbo_shadowdata[19].Set(32767.0f, -32767.0f, -32767.0f, 0, 0);
if (gl.buffermethod == BM_DEFERRED)
{
Map();
memcpy(map, &vbo_shadowdata[0], mNumReserved * sizeof(FFlatVertex));
Unmap();
}
}
FFlatVertexBuffer::~FFlatVertexBuffer()
@ -195,7 +217,7 @@ FFlatVertexBuffer::~FFlatVertexBuffer()
glUnmapBuffer(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
else
if (gl.buffermethod == BM_CLIENTARRAY)
{
delete[] map;
}
@ -208,7 +230,7 @@ void FFlatVertexBuffer::BindVBO()
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
if (gl.glslversion > 0)
{
if (vbo_id != 0) // set this up only if there is an actual buffer.
if (gl.buffermethod != BM_CLIENTARRAY)
{
glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->x);
glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->u);
@ -226,12 +248,37 @@ void FFlatVertexBuffer::BindVBO()
}
else
{
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(FFlatVertex), &map->x);
glTexCoordPointer(2, GL_FLOAT, sizeof(FFlatVertex), &map->u);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
}
void FFlatVertexBuffer::Map()
{
if (gl.buffermethod == BM_DEFERRED)
{
unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
gl_RenderState.ResetVertexBuffer();
map = (FFlatVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, bytesize, GL_MAP_WRITE_BIT|GL_MAP_UNSYNCHRONIZED_BIT);
}
}
void FFlatVertexBuffer::Unmap()
{
if (gl.buffermethod == BM_DEFERRED)
{
unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
gl_RenderState.ResetVertexBuffer();
glUnmapBuffer(GL_ARRAY_BUFFER);
map = nullptr;
}
}
//==========================================================================
//
// Initialize a single vertex
@ -412,7 +459,9 @@ void FFlatVertexBuffer::CreateVBO()
vbo_shadowdata.Resize(mNumReserved);
CreateFlatVBO();
mCurIndex = mIndex = vbo_shadowdata.Size();
Map();
memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex));
Unmap();
}
//==========================================================================

View file

@ -149,6 +149,9 @@ public:
mCurIndex = mIndex;
}
void Map();
void Unmap();
private:
int CreateSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor);
int CreateSectorVertices(sector_t *sec, const secplane_t &plane, int floor);

View file

@ -114,7 +114,7 @@ void FGLRenderer::RenderScreenQuad()
{
mVBO->BindVBO();
gl_RenderState.ResetVertexBuffer();
glDrawArrays(GL_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4);
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4);
}
//-----------------------------------------------------------------------------

View file

@ -163,8 +163,8 @@ void GLPortal::DrawPortalStencil()
}
if (NeedCap() && lines.Size() > 1)
{
glDrawArrays(GL_TRIANGLE_FAN, FFlatVertexBuffer::STENCILTOP_INDEX, 4);
glDrawArrays(GL_TRIANGLE_FAN, FFlatVertexBuffer::STENCILBOTTOM_INDEX, 4);
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, FFlatVertexBuffer::STENCILTOP_INDEX, 4);
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, FFlatVertexBuffer::STENCILBOTTOM_INDEX, 4);
}
}
@ -1178,9 +1178,9 @@ void GLHorizonPortal::DrawContents()
for (unsigned i = 0; i < vcount; i += 4)
{
glDrawArrays(GL_TRIANGLE_STRIP, voffset + i, 4);
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, voffset + i, 4);
}
glDrawArrays(GL_TRIANGLE_STRIP, voffset + vcount, 10);
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, voffset + vcount, 10);
gl_RenderState.EnableTextureMatrix(false);
PortalAll.Unclock();

View file

@ -284,6 +284,7 @@ void FGLRenderer::CreateScene()
for(unsigned i=0;i<portals.Size(); i++) portals[i]->glportal = NULL;
gl_spriteindex=0;
Bsp.Clock();
GLRenderer->mVBO->Map();
R_SetView();
validcount++; // used for processing sidedefs only once by the renderer.
gl_RenderBSPNode (nodes + numnodes - 1);
@ -295,6 +296,7 @@ void FGLRenderer::CreateScene()
gl_drawinfo->HandleMissingTextures(); // Missing upper/lower textures
gl_drawinfo->HandleHackedSubsectors(); // open sector hacks for deep water
gl_drawinfo->ProcessSectorStacks(); // merge visplanes of sector stacks
GLRenderer->mVBO->Unmap();
ProcessAll.Unclock();
@ -525,7 +527,7 @@ void gl_FillScreen()
gl_RenderState.EnableTexture(false);
gl_RenderState.Apply();
// The fullscreen quad is stored at index 4 in the main vertex buffer.
glDrawArrays(GL_TRIANGLE_STRIP, FFlatVertexBuffer::FULLSCREEN_INDEX, 4);
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, FFlatVertexBuffer::FULLSCREEN_INDEX, 4);
}
//==========================================================================

View file

@ -125,7 +125,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
vp_comb = "#version 400 core\n#extension GL_ARB_shader_storage_buffer_object : require\n#define SHADER_STORAGE_LIGHTS\n";
}
}
//if (gl.buffermethod == BM_DEFERRED)
if (gl.buffermethod == BM_DEFERRED)
{
vp_comb << "#define USE_QUAD_DRAWER\n";
}

View file

@ -204,8 +204,12 @@ void gl_LoadExtensions()
}
else if (gl.version < 3.0f)
{
//if (CheckExtension("GL_NV_GPU_shader4") || CheckExtension("GL_EXT_GPU_shader4")) gl.glslversion = 1.21f; // for pre-3.0 drivers that support capable hardware. Needed for Apple.
//else gl.glslversion = 0;
if (CheckExtension("GL_NV_GPU_shader4") || CheckExtension("GL_EXT_GPU_shader4")) gl.glslversion = 1.21f; // for pre-3.0 drivers that support capable hardware. Needed for Apple.
else
{
gl.buffermethod = BM_CLIENTARRAY;
gl.glslversion = 0;
}
if (!CheckExtension("GL_EXT_packed_float")) gl.flags |= RFL_NO_RGBA16F;
if (!CheckExtension("GL_EXT_packed_depth_stencil")) gl.flags |= RFL_NO_DEPTHSTENCIL;