diff --git a/BREAKING-CHANGES.txt b/BREAKING-CHANGES.txt index 12372b0621..916b6e11d8 100644 --- a/BREAKING-CHANGES.txt +++ b/BREAKING-CHANGES.txt @@ -4,6 +4,26 @@ JUCE breaking changes Develop ======= +Change +------ +The JUCE_GLSL_VERSION preprocessor definition has been removed. + +Possible Issues +--------------- +Code which used this definition will no longer compile. + +Workaround +---------- +Use OpenGLHelpers::getGLSLVersionString to retrieve a version string which is +consistent with the capabilities of the current OpenGL context. + +Rationale +--------- +A compile-time version string is not very useful, as OpenGL versions and +capabilities can change at runtime. Replacing this macro with a function allows +querying the capabilities of the current context at runtime. + + Change ------ The minimum support CMake version is now 3.15. diff --git a/modules/juce_opengl/juce_opengl.h b/modules/juce_opengl/juce_opengl.h index ea7e3d80e3..32ee669bf7 100644 --- a/modules/juce_opengl/juce_opengl.h +++ b/modules/juce_opengl/juce_opengl.h @@ -70,16 +70,6 @@ #include -//============================================================================== -/** This macro is a helper for use in GLSL shader code which needs to compile on both OpenGL 2.1 and OpenGL 3.0. - It's mandatory in OpenGL 3.0 to specify the GLSL version. -*/ -#if JUCE_OPENGL_ES - #define JUCE_GLSL_VERSION "#version 300 es" -#else - #define JUCE_GLSL_VERSION "#version 150" -#endif - //============================================================================== #if JUCE_OPENGL_ES || defined (DOXYGEN) /** This macro is a helper for use in GLSL shader code which needs to compile on both GLES and desktop GL. diff --git a/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp b/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp index 5993097350..3ead2ef621 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp @@ -26,6 +26,88 @@ namespace juce { +class Version +{ +public: + constexpr Version() = default; + + constexpr explicit Version (int majorIn) + : Version (majorIn, 0) {} + + constexpr Version (int majorIn, int minorIn) + : major (majorIn), minor (minorIn) {} + + int major = 0, minor = 0; + + constexpr bool operator== (const Version& other) const noexcept + { + return toTuple() == other.toTuple(); + } + + constexpr bool operator!= (const Version& other) const noexcept + { + return toTuple() != other.toTuple(); + } + + constexpr bool operator< (const Version& other) const noexcept + { + return toTuple() < other.toTuple(); + } + + constexpr bool operator<= (const Version& other) const noexcept + { + return toTuple() <= other.toTuple(); + } + + constexpr bool operator> (const Version& other) const noexcept + { + return toTuple() > other.toTuple(); + } + + constexpr bool operator>= (const Version& other) const noexcept + { + return toTuple() >= other.toTuple(); + } + +private: + constexpr std::tuple toTuple() const noexcept + { + return std::make_tuple (major, minor); + } +}; + + +template +static auto* findNullTerminator (const Char* ptr) +{ + while (*ptr != 0) + ++ptr; + + return ptr; +} + +static Version getOpenGLVersion() +{ + const auto* versionBegin = glGetString (GL_VERSION); + + if (versionBegin == nullptr) + return {}; + + const auto* versionEnd = findNullTerminator (versionBegin); + const std::string versionString (versionBegin, versionEnd); + const auto spaceSeparated = StringArray::fromTokens (versionString.c_str(), false); + + if (spaceSeparated.isEmpty()) + return {}; + + const auto pointSeparated = StringArray::fromTokens (spaceSeparated[0], ".", ""); + + const auto major = pointSeparated[0].getIntValue(); + const auto minor = pointSeparated[1].getIntValue(); + + return { major, minor }; +} + void OpenGLHelpers::resetErrorState() { while (glGetError() != GL_NO_ERROR) {} @@ -81,9 +163,23 @@ void OpenGLHelpers::enableScissorTest (Rectangle clip) glScissor (clip.getX(), clip.getY(), clip.getWidth(), clip.getHeight()); } +String OpenGLHelpers::getGLSLVersionString() +{ + if (getOpenGLVersion() >= Version (3, 2)) + { + #if JUCE_OPENGL_ES + return "#version 300 es"; + #else + return "#version 150"; + #endif + } + + return "#version 110"; +} + String OpenGLHelpers::translateVertexShaderToV3 (const String& code) { - if (OpenGLShaderProgram::getLanguageVersion() > 1.2) + if (getOpenGLVersion() >= Version (3, 2)) { String output; @@ -109,7 +205,7 @@ String OpenGLHelpers::translateVertexShaderToV3 (const String& code) output = code.replace ("attribute", "in"); #endif - return JUCE_GLSL_VERSION "\n" + output.replace ("varying", "out"); + return getGLSLVersionString() + "\n" + output.replace ("varying", "out"); } return code; @@ -117,8 +213,8 @@ String OpenGLHelpers::translateVertexShaderToV3 (const String& code) String OpenGLHelpers::translateFragmentShaderToV3 (const String& code) { - if (OpenGLShaderProgram::getLanguageVersion() > 1.2) - return JUCE_GLSL_VERSION "\n" + if (getOpenGLVersion() >= Version (3, 2)) + return getGLSLVersionString() + "\n" "out " JUCE_MEDIUMP " vec4 fragColor;\n" + code.replace ("varying", "in") .replace ("texture2D", "texture") diff --git a/modules/juce_opengl/opengl/juce_OpenGLHelpers.h b/modules/juce_opengl/opengl/juce_OpenGLHelpers.h index cef11c2e5f..d07e93bf9a 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLHelpers.h +++ b/modules/juce_opengl/opengl/juce_OpenGLHelpers.h @@ -52,6 +52,11 @@ public: /** Returns the address of a named GL extension function */ static void* getExtensionFunction (const char* functionName); + /** Returns a version string such as "#version 150" suitable for prefixing a GLSL + shader on this platform. + */ + static String getGLSLVersionString(); + /** Makes some simple textual changes to a shader program to try to convert old GLSL keywords to their v3 equivalents.