| @@ -841,7 +841,9 @@ public: | |||
| glEnable (GL_BLEND); | |||
| glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |||
| glActiveTexture (GL_TEXTURE0); | |||
| glEnable (GL_TEXTURE_2D); | |||
| if (! openGLContext.isCoreProfile()) | |||
| glEnable (GL_TEXTURE_2D); | |||
| glViewport (0, 0, | |||
| roundToInt (desktopScale * (float) bounds.getWidth()), | |||
| @@ -240,22 +240,6 @@ private: | |||
| OpenGLTargetSaver& operator= (const OpenGLTargetSaver&); | |||
| }; | |||
| static bool contextRequiresTexture2DEnableDisable() | |||
| { | |||
| #if JUCE_OPENGL_ES | |||
| return false; | |||
| #else | |||
| clearGLError(); | |||
| GLint mask = 0; | |||
| glGetIntegerv (GL_CONTEXT_PROFILE_MASK, &mask); | |||
| if (glGetError() == GL_INVALID_ENUM) | |||
| return true; | |||
| return (mask & (GLint) GL_CONTEXT_CORE_PROFILE_BIT) == 0; | |||
| #endif | |||
| } | |||
| } // namespace juce | |||
| //============================================================================== | |||
| @@ -537,7 +537,7 @@ public: | |||
| void drawComponentBuffer() | |||
| { | |||
| if (contextRequiresTexture2DEnableDisable()) | |||
| if (! isCoreProfile()) | |||
| glEnable (GL_TEXTURE_2D); | |||
| #if JUCE_WINDOWS | |||
| @@ -644,6 +644,7 @@ public: | |||
| if (getOpenGLVersion() >= Version { 4, 3 } && glDebugMessageCallback != nullptr) | |||
| { | |||
| glEnable (GL_DEBUG_OUTPUT); | |||
| glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS); | |||
| glDebugMessageCallback ([] (GLenum, GLenum type, GLuint, GLenum severity, GLsizei, const GLchar* message, const void*) | |||
| { | |||
| // This may reiterate issues that are also flagged by JUCE_CHECK_OPENGL_ERROR. | |||
| @@ -674,17 +675,10 @@ public: | |||
| return InitResult::success; | |||
| } | |||
| /* 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 | |||
| bool isCoreProfile() const | |||
| { | |||
| #if JUCE_OPENGL_ES | |||
| return false; | |||
| return true; | |||
| #else | |||
| clearGLError(); | |||
| GLint mask = 0; | |||
| @@ -699,6 +693,22 @@ public: | |||
| #endif | |||
| } | |||
| /* 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 | |||
| return isCoreProfile(); | |||
| #endif | |||
| } | |||
| //============================================================================== | |||
| struct BlockingWorker : public OpenGLContext::AsyncWorker | |||
| { | |||
| @@ -1443,6 +1453,12 @@ void* OpenGLContext::getRawContext() const noexcept | |||
| return nativeContext != nullptr ? nativeContext->getRawContext() : nullptr; | |||
| } | |||
| bool OpenGLContext::isCoreProfile() const | |||
| { | |||
| auto* c = getCachedImage(); | |||
| return c != nullptr && c->isCoreProfile(); | |||
| } | |||
| OpenGLContext::CachedImage* OpenGLContext::getCachedImage() const noexcept | |||
| { | |||
| if (auto* comp = getTargetComponent()) | |||
| @@ -133,7 +133,16 @@ public: | |||
| /** Returns true if non-power-of-two textures are supported in this context. */ | |||
| bool isTextureNpotSupported() const; | |||
| /** OpenGL versions, used by setOpenGLVersionRequired(). */ | |||
| /** OpenGL versions, used by setOpenGLVersionRequired(). | |||
| The Core profile doesn't include some legacy functionality, including the | |||
| fixed-function pipeline. | |||
| The Compatibility profile is backwards-compatible, and includes functionality | |||
| deprecated in the Core profile. However, not all implementations provide | |||
| compatibility profiles targeting later versions of OpenGL. To run on the | |||
| broadest range of hardware, using the 3.2 Core profile is recommended. | |||
| */ | |||
| enum OpenGLVersion | |||
| { | |||
| defaultGLVersion = 0, ///< Whatever the device decides to give us, normally a compatibility profile | |||
| @@ -285,6 +294,12 @@ public: | |||
| */ | |||
| void* getRawContext() const noexcept; | |||
| /** Returns true if this context is using the core profile. | |||
| @see OpenGLVersion | |||
| */ | |||
| bool isCoreProfile() const; | |||
| /** This structure holds a set of dynamically loaded GL functions for use on this context. */ | |||
| OpenGLExtensionFunctions extensions; | |||
| @@ -216,7 +216,9 @@ bool OpenGLFrameBuffer::initialise (OpenGLFrameBuffer& other) | |||
| pimpl->bind(); | |||
| #if ! JUCE_ANDROID | |||
| glEnable (GL_TEXTURE_2D); | |||
| if (! pimpl->context.isCoreProfile()) | |||
| glEnable (GL_TEXTURE_2D); | |||
| clearGLError(); | |||
| #endif | |||
| glBindTexture (GL_TEXTURE_2D, p->textureID); | |||
| @@ -1086,7 +1086,7 @@ struct StateHelpers | |||
| GLuint currentTextureID[numTextures]; | |||
| int texturesEnabled = 0, currentActiveTexture = -1; | |||
| const OpenGLContext& context; | |||
| const bool needsToEnableTexture = contextRequiresTexture2DEnableDisable(); | |||
| const bool needsToEnableTexture = ! context.isCoreProfile(); | |||
| ActiveTextures& operator= (const ActiveTextures&); | |||
| }; | |||
| @@ -1784,7 +1784,10 @@ struct NonShaderContext : public LowLevelGraphicsSoftwareRenderer | |||
| #if ! JUCE_ANDROID | |||
| target.context.extensions.glActiveTexture (GL_TEXTURE0); | |||
| glEnable (GL_TEXTURE_2D); | |||
| if (! target.context.isCoreProfile()) | |||
| glEnable (GL_TEXTURE_2D); | |||
| clearGLError(); | |||
| #endif | |||