| @@ -841,7 +841,9 @@ public: | |||||
| glEnable (GL_BLEND); | glEnable (GL_BLEND); | ||||
| glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||||
| glActiveTexture (GL_TEXTURE0); | glActiveTexture (GL_TEXTURE0); | ||||
| glEnable (GL_TEXTURE_2D); | |||||
| if (! openGLContext.isCoreProfile()) | |||||
| glEnable (GL_TEXTURE_2D); | |||||
| glViewport (0, 0, | glViewport (0, 0, | ||||
| roundToInt (desktopScale * (float) bounds.getWidth()), | roundToInt (desktopScale * (float) bounds.getWidth()), | ||||
| @@ -240,22 +240,6 @@ private: | |||||
| OpenGLTargetSaver& operator= (const OpenGLTargetSaver&); | 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 | } // namespace juce | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -537,7 +537,7 @@ public: | |||||
| void drawComponentBuffer() | void drawComponentBuffer() | ||||
| { | { | ||||
| if (contextRequiresTexture2DEnableDisable()) | |||||
| if (! isCoreProfile()) | |||||
| glEnable (GL_TEXTURE_2D); | glEnable (GL_TEXTURE_2D); | ||||
| #if JUCE_WINDOWS | #if JUCE_WINDOWS | ||||
| @@ -644,6 +644,7 @@ public: | |||||
| if (getOpenGLVersion() >= Version { 4, 3 } && glDebugMessageCallback != nullptr) | if (getOpenGLVersion() >= Version { 4, 3 } && glDebugMessageCallback != nullptr) | ||||
| { | { | ||||
| glEnable (GL_DEBUG_OUTPUT); | glEnable (GL_DEBUG_OUTPUT); | ||||
| glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS); | |||||
| glDebugMessageCallback ([] (GLenum, GLenum type, GLuint, GLenum severity, GLsizei, const GLchar* message, const void*) | 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. | // This may reiterate issues that are also flagged by JUCE_CHECK_OPENGL_ERROR. | ||||
| @@ -674,17 +675,10 @@ public: | |||||
| return InitResult::success; | 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 | #if JUCE_OPENGL_ES | ||||
| return false; | |||||
| return true; | |||||
| #else | #else | ||||
| clearGLError(); | clearGLError(); | ||||
| GLint mask = 0; | GLint mask = 0; | ||||
| @@ -699,6 +693,22 @@ public: | |||||
| #endif | #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 | struct BlockingWorker : public OpenGLContext::AsyncWorker | ||||
| { | { | ||||
| @@ -1443,6 +1453,12 @@ void* OpenGLContext::getRawContext() const noexcept | |||||
| return nativeContext != nullptr ? nativeContext->getRawContext() : nullptr; | return nativeContext != nullptr ? nativeContext->getRawContext() : nullptr; | ||||
| } | } | ||||
| bool OpenGLContext::isCoreProfile() const | |||||
| { | |||||
| auto* c = getCachedImage(); | |||||
| return c != nullptr && c->isCoreProfile(); | |||||
| } | |||||
| OpenGLContext::CachedImage* OpenGLContext::getCachedImage() const noexcept | OpenGLContext::CachedImage* OpenGLContext::getCachedImage() const noexcept | ||||
| { | { | ||||
| if (auto* comp = getTargetComponent()) | if (auto* comp = getTargetComponent()) | ||||
| @@ -133,7 +133,16 @@ public: | |||||
| /** Returns true if non-power-of-two textures are supported in this context. */ | /** Returns true if non-power-of-two textures are supported in this context. */ | ||||
| bool isTextureNpotSupported() const; | 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 | enum OpenGLVersion | ||||
| { | { | ||||
| defaultGLVersion = 0, ///< Whatever the device decides to give us, normally a compatibility profile | defaultGLVersion = 0, ///< Whatever the device decides to give us, normally a compatibility profile | ||||
| @@ -285,6 +294,12 @@ public: | |||||
| */ | */ | ||||
| void* getRawContext() const noexcept; | 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. */ | /** This structure holds a set of dynamically loaded GL functions for use on this context. */ | ||||
| OpenGLExtensionFunctions extensions; | OpenGLExtensionFunctions extensions; | ||||
| @@ -216,7 +216,9 @@ bool OpenGLFrameBuffer::initialise (OpenGLFrameBuffer& other) | |||||
| pimpl->bind(); | pimpl->bind(); | ||||
| #if ! JUCE_ANDROID | #if ! JUCE_ANDROID | ||||
| glEnable (GL_TEXTURE_2D); | |||||
| if (! pimpl->context.isCoreProfile()) | |||||
| glEnable (GL_TEXTURE_2D); | |||||
| clearGLError(); | clearGLError(); | ||||
| #endif | #endif | ||||
| glBindTexture (GL_TEXTURE_2D, p->textureID); | glBindTexture (GL_TEXTURE_2D, p->textureID); | ||||
| @@ -1086,7 +1086,7 @@ struct StateHelpers | |||||
| GLuint currentTextureID[numTextures]; | GLuint currentTextureID[numTextures]; | ||||
| int texturesEnabled = 0, currentActiveTexture = -1; | int texturesEnabled = 0, currentActiveTexture = -1; | ||||
| const OpenGLContext& context; | const OpenGLContext& context; | ||||
| const bool needsToEnableTexture = contextRequiresTexture2DEnableDisable(); | |||||
| const bool needsToEnableTexture = ! context.isCoreProfile(); | |||||
| ActiveTextures& operator= (const ActiveTextures&); | ActiveTextures& operator= (const ActiveTextures&); | ||||
| }; | }; | ||||
| @@ -1784,7 +1784,10 @@ struct NonShaderContext : public LowLevelGraphicsSoftwareRenderer | |||||
| #if ! JUCE_ANDROID | #if ! JUCE_ANDROID | ||||
| target.context.extensions.glActiveTexture (GL_TEXTURE0); | target.context.extensions.glActiveTexture (GL_TEXTURE0); | ||||
| glEnable (GL_TEXTURE_2D); | |||||
| if (! target.context.isCoreProfile()) | |||||
| glEnable (GL_TEXTURE_2D); | |||||
| clearGLError(); | clearGLError(); | ||||
| #endif | #endif | ||||