diff --git a/modules/juce_opengl/opengl/juce_OpenGLContext.cpp b/modules/juce_opengl/opengl/juce_OpenGLContext.cpp index 5593afb88a..aa9b750cd7 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLContext.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLContext.cpp @@ -409,7 +409,7 @@ public: void bindVertexArray() noexcept { - if (openGLVersion.major >= 3) + if (shouldUseCustomVAO()) if (vertexArrayObject != 0) context.extensions.glBindVertexArray (vertexArrayObject); } @@ -616,9 +616,7 @@ public: gl::loadFunctions(); - openGLVersion = getOpenGLVersion(); - - if (openGLVersion.major >= 3) + if (shouldUseCustomVAO()) { context.extensions.glGenVertexArrays (1, &vertexArrayObject); bindVertexArray(); @@ -662,6 +660,31 @@ public: nativeContext->shutdownOnRenderThread(); } + /* Returns true if the context requires a non-zero vertex array object (VAO) to be bound. + + If the context is a compatibility context, we can just pretend that VAOs don't exist, + and use the default VAO all the time instead. This provides a more consistent experience + in user code, which might make calls (like glVertexPointer()) that only work when VAO 0 is + bound in OpenGL 3.2+. + */ + bool shouldUseCustomVAO() const + { + #if JUCE_OPENGL_ES + return false; + #else + clearGLError(); + GLint mask = 0; + glGetIntegerv (GL_CONTEXT_PROFILE_MASK, &mask); + + // The context isn't aware of the profile mask, so it pre-dates the core profile + if (glGetError() == GL_INVALID_ENUM) + return false; + + // Also assumes a compatibility profile if the mask is completely empty for some reason + return (mask & (GLint) GL_CONTEXT_CORE_PROFILE_BIT) != 0; + #endif + } + //============================================================================== struct BlockingWorker : public OpenGLContext::AsyncWorker { @@ -752,7 +775,6 @@ public: OpenGLContext& context; Component& component; - Version openGLVersion; OpenGLFrameBuffer cachedImageFrameBuffer; RectangleList validArea; Rectangle lastScreenBounds;