diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index 223fb67f87..a0865c435e 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -57,12 +57,10 @@ // //========================================================================== -FVertexBuffer::FVertexBuffer() +FVertexBuffer::FVertexBuffer(bool wantbuffer) { - vao_id = vbo_id = 0; - glGenBuffers(1, &vbo_id); - glGenVertexArrays(1, &vao_id); - + vbo_id = 0; + if (wantbuffer) glGenBuffers(1, &vbo_id); } FVertexBuffer::~FVertexBuffer() @@ -71,15 +69,6 @@ FVertexBuffer::~FVertexBuffer() { glDeleteBuffers(1, &vbo_id); } - if (vao_id != 0) - { - glDeleteVertexArrays(1, &vao_id); - } -} - -void FVertexBuffer::BindVBO() -{ - glBindVertexArray(vao_id); } //========================================================================== @@ -89,7 +78,7 @@ void FVertexBuffer::BindVBO() //========================================================================== FFlatVertexBuffer::FFlatVertexBuffer() -: FVertexBuffer() +: FVertexBuffer(!!(gl.flags & RFL_BUFFER_STORAGE)) { if (gl.flags & RFL_BUFFER_STORAGE) { @@ -97,17 +86,10 @@ FFlatVertexBuffer::FFlatVertexBuffer() 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); - - glBindVertexArray(vao_id); - glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - 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); - glBindVertexArray(0); } else { + // 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]; } @@ -124,6 +106,26 @@ FFlatVertexBuffer::~FFlatVertexBuffer() } } + +void FFlatVertexBuffer::BindVBO() +{ + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + if (vbo_id != 0) // set this up only if there is an actual buffer. + { + 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); + } + glDisableVertexAttribArray(VATTR_COLOR); + glDisableVertexAttribArray(VATTR_VERTEX2); +} + //========================================================================== // // immediate mode fallback for drivers without GL_ARB_buffer_storage @@ -138,7 +140,7 @@ void FFlatVertexBuffer::ImmRenderBuffer(unsigned int primtype, unsigned int offs // this will only get called if we can't acquire a persistently mapped buffer. #ifndef CORE_PROFILE glBegin(primtype); - if (gl.compatibility > CMPT_GL2) + if (gl.glslversion > 0) { for (unsigned int i = 0; i < count; i++) { diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index 12b536f105..c56cadcbac 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -15,12 +15,11 @@ class FVertexBuffer { protected: unsigned int vbo_id; - unsigned int vao_id; public: - FVertexBuffer(); + FVertexBuffer(bool wantbuffer = true); virtual ~FVertexBuffer(); - void BindVBO(); + virtual void BindVBO() = 0; }; struct FFlatVertex @@ -37,6 +36,7 @@ struct FFlatVertex u = uu; v = vv; } + void BindVBO(); }; #define VTO ((FFlatVertex*)NULL) @@ -62,6 +62,8 @@ public: FFlatVertexBuffer(); ~FFlatVertexBuffer(); + void BindVBO(); + void CreateVBO(); void CheckUpdate(sector_t *sector); @@ -165,6 +167,7 @@ public: FSkyVertexBuffer(); virtual ~FSkyVertexBuffer(); void RenderDome(FMaterial *tex, int mode); + void BindVBO(); }; @@ -208,6 +211,7 @@ public: void UnlockIndexBuffer(); unsigned int SetupFrame(unsigned int frame1, unsigned int frame2); + void BindVBO(); }; #define VMO ((FModelVertex*)NULL) diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index 6050ac24d4..abf3efcd5b 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -117,20 +117,27 @@ void gl_FlushModels() FModelVertexBuffer::FModelVertexBuffer(bool needindex) { - glBindVertexArray(vao_id); - ibo_id = 0; if (needindex) { glGenBuffers(1, &ibo_id); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id); } +} +//=========================================================================== +// +// +// +//=========================================================================== + +void FModelVertexBuffer::BindVBO() +{ + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id); glBindBuffer(GL_ARRAY_BUFFER, vbo_id); glEnableVertexAttribArray(VATTR_VERTEX); glEnableVertexAttribArray(VATTR_TEXCOORD); glEnableVertexAttribArray(VATTR_VERTEX2); - glBindVertexArray(0); + glDisableVertexAttribArray(VATTR_COLOR); } //=========================================================================== diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 3e198b1a04..cca2e9b2bc 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -103,6 +103,14 @@ void gl_FlushModels(); void FGLRenderer::Initialize() { + // Only needed for the core profile, because someone decided it was a good idea to remove the default VAO. + if (gl.version >= 4.0) + { + glGenVertexArrays(1, &mVAOID); + glBindVertexArray(mVAOID); + } + else mVAOID = 0; + glpart2 = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/glpart2.png"), FTexture::TEX_MiscPatch); glpart = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/glpart.png"), FTexture::TEX_MiscPatch); mirrortexture = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/mirror.png"), FTexture::TEX_MiscPatch); @@ -113,6 +121,7 @@ void FGLRenderer::Initialize() else mLights = NULL; gl_RenderState.SetVertexBuffer(mVBO); mFBID = 0; + SetupLevel(); mShaderManager = new FShaderManager; mSamplerManager = new FSamplerManager; @@ -133,6 +142,12 @@ FGLRenderer::~FGLRenderer() if (glpart) delete glpart; if (mirrortexture) delete mirrortexture; if (mFBID != 0) glDeleteFramebuffers(1, &mFBID); + if (mVAOID != 0) + { + glBindVertexArray(0); + glDeleteVertexArrays(1, &mVAOID); + } + } //=========================================================================== diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index a2f4c7d349..f266bcd370 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -69,6 +69,7 @@ public: FSamplerManager *mSamplerManager; int gl_spriteindex; unsigned int mFBID; + unsigned int mVAOID; FTexture *glpart2; FTexture *glpart; diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 892e384e76..1398191e12 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -279,7 +279,7 @@ void FRenderState::Apply() else mVertexBuffer->BindVBO(); mCurrentVertexBuffer = mVertexBuffer; } - if (gl.compatibility > CMPT_GL2) + if (gl.glslversion > 0) { ApplyShader(); } diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index 69968ddf7f..ae78b0291a 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -78,8 +78,14 @@ extern int skyfog; FSkyVertexBuffer::FSkyVertexBuffer() { CreateDome(); +} - glBindVertexArray(vao_id); +FSkyVertexBuffer::~FSkyVertexBuffer() +{ +} + +void FSkyVertexBuffer::BindVBO() +{ glBindBuffer(GL_ARRAY_BUFFER, vbo_id); glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FSkyVertex), &VSO->x); glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FSkyVertex), &VSO->u); @@ -87,12 +93,7 @@ FSkyVertexBuffer::FSkyVertexBuffer() glEnableVertexAttribArray(VATTR_VERTEX); glEnableVertexAttribArray(VATTR_TEXCOORD); glEnableVertexAttribArray(VATTR_COLOR); - glBindVertexArray(0); - -} - -FSkyVertexBuffer::~FSkyVertexBuffer() -{ + glDisableVertexAttribArray(VATTR_VERTEX2); } //----------------------------------------------------------------------------- diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 4a82251d0e..af6accdb57 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -129,7 +129,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * if (gl.lightmethod == LM_SOFTWARE) { - if (gl.compatibility >= CMPT_GL3) + if (gl.glslversion >= 1.3) { vp_comb = "#version 130\n"; } @@ -201,7 +201,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * } } - if (gl.compatibility < CMPT_GL3) + if (gl.glslversion < 1.3) { PatchVertShader(vp_comb); PatchFragShader(fp_comb); @@ -439,7 +439,7 @@ static const FEffectShader effectshaders[]= FShaderManager::FShaderManager() { - if (gl.compatibility > CMPT_GL2) CompileShaders(); + if (gl.glslversion > 0) CompileShaders(); } //========================================================================== @@ -450,7 +450,7 @@ FShaderManager::FShaderManager() FShaderManager::~FShaderManager() { - if (gl.compatibility > CMPT_GL2) Clean(); + if (gl.glslversion > 0) Clean(); } //========================================================================== @@ -592,7 +592,7 @@ EXTERN_CVAR(Int, gl_fuzztype) void FShaderManager::ApplyMatrices(VSMatrix *proj, VSMatrix *view) { - if (gl.compatibility == CMPT_GL2) + if (gl.glslversion == 0) { glMatrixMode(GL_PROJECTION); glLoadMatrixf(proj->get()); diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index d2b69ad0a5..12e879a239 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -158,25 +158,24 @@ void gl_LoadExtensions() if (CheckExtension("GL_ARB_texture_compression")) gl.flags |= RFL_TEXTURE_COMPRESSION; if (CheckExtension("GL_EXT_texture_compression_s3tc")) gl.flags |= RFL_TEXTURE_COMPRESSION_S3TC; - if (Args->CheckParm("-noshader")) + if (Args->CheckParm("-noshader") || gl.glslversion < 1.2f) { - gl.version = 2.1f; - gl.compatibility = CMPT_GL2; // force the low end path + gl.version = 2.11f; + gl.glslversion = 0; } else if (gl.version < 3.0f) { - if (CheckExtension("GL_NV_GPU_shader4") || CheckExtension("GL_EXT_GPU_shader4")) gl.compatibility = CMPT_GL2_SHADER; // for pre-3.0 drivers that support capable hardware. Needed for Apple. - else gl.compatibility = CMPT_GL2; + 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; } else if (gl.version < 4.f) { if (strstr(gl.vendorstring, "ATI Tech")) { - gl.version = 2.1f; - gl.compatibility = CMPT_GL2_SHADER; // most of these drivers are irreperably broken with GLSL 1.3 and higher. + gl.version = 2.11f; + gl.glslversion = 1.21f; gl.lightmethod = LM_SOFTWARE; // do not use uniform buffers with the fallback shader, it may cause problems. } - else gl.compatibility = CMPT_GL3; } else { @@ -194,13 +193,11 @@ void gl_LoadExtensions() } } gl.flags |= RFL_BUFFER_STORAGE; - gl.compatibility = CMPT_GL4; gl.lightmethod = LM_DIRECT; } else { gl.version = 3.3f; - gl.compatibility = CMPT_GL3; } } diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index 5248c2f8b1..433c2327ce 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -48,7 +48,6 @@ struct RenderContext unsigned int maxuniformblock; unsigned int uniformblockalignment; int lightmethod; - int compatibility; float version; float glslversion; int max_texturesize; diff --git a/src/gl/textures/gl_hqresize.cpp b/src/gl/textures/gl_hqresize.cpp index 993e9f138b..785f3c6e94 100644 --- a/src/gl/textures/gl_hqresize.cpp +++ b/src/gl/textures/gl_hqresize.cpp @@ -264,7 +264,7 @@ unsigned char *gl_CreateUpsampledTextureBuffer ( const FTexture *inputTexture, u return inputBuffer; // [BB] Don't upsample non-shader handled warped textures. Needs too much memory and time - if (gl.compatibility == CMPT_GL2 && inputTexture->bWarped) + if (gl.glslversion == 0 && inputTexture->bWarped) return inputBuffer; // already scaled?