The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

247 lines
6.7KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2022 - Raw Material Software Limited
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 7 End-User License
  8. Agreement and JUCE Privacy Policy.
  9. End User License Agreement: www.juce.com/juce-7-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. namespace juce
  19. {
  20. class Version
  21. {
  22. public:
  23. constexpr Version() = default;
  24. constexpr explicit Version (int majorIn)
  25. : Version (majorIn, 0) {}
  26. constexpr Version (int majorIn, int minorIn)
  27. : major (majorIn), minor (minorIn) {}
  28. int major = 0, minor = 0;
  29. constexpr bool operator== (const Version& other) const noexcept
  30. {
  31. return toTuple() == other.toTuple();
  32. }
  33. constexpr bool operator!= (const Version& other) const noexcept
  34. {
  35. return toTuple() != other.toTuple();
  36. }
  37. constexpr bool operator< (const Version& other) const noexcept
  38. {
  39. return toTuple() < other.toTuple();
  40. }
  41. constexpr bool operator<= (const Version& other) const noexcept
  42. {
  43. return toTuple() <= other.toTuple();
  44. }
  45. constexpr bool operator> (const Version& other) const noexcept
  46. {
  47. return toTuple() > other.toTuple();
  48. }
  49. constexpr bool operator>= (const Version& other) const noexcept
  50. {
  51. return toTuple() >= other.toTuple();
  52. }
  53. private:
  54. constexpr std::tuple<int, int> toTuple() const noexcept
  55. {
  56. return std::make_tuple (major, minor);
  57. }
  58. };
  59. template <typename Char>
  60. static auto* findNullTerminator (const Char* ptr)
  61. {
  62. while (*ptr != 0)
  63. ++ptr;
  64. return ptr;
  65. }
  66. static Version getOpenGLVersion()
  67. {
  68. const auto* versionBegin = glGetString (GL_VERSION);
  69. if (versionBegin == nullptr)
  70. return {};
  71. const auto* versionEnd = findNullTerminator (versionBegin);
  72. const std::string versionString (versionBegin, versionEnd);
  73. const auto spaceSeparated = StringArray::fromTokens (versionString.c_str(), false);
  74. for (const auto& token : spaceSeparated)
  75. {
  76. const auto pointSeparated = StringArray::fromTokens (token, ".", "");
  77. const auto major = pointSeparated[0].getIntValue();
  78. const auto minor = pointSeparated[1].getIntValue();
  79. if (major != 0)
  80. return { major, minor };
  81. }
  82. return {};
  83. }
  84. void OpenGLHelpers::resetErrorState()
  85. {
  86. while (glGetError() != GL_NO_ERROR) {}
  87. }
  88. void* OpenGLHelpers::getExtensionFunction (const char* functionName)
  89. {
  90. #if JUCE_WINDOWS
  91. return (void*) wglGetProcAddress (functionName);
  92. #elif JUCE_LINUX || JUCE_BSD
  93. return (void*) glXGetProcAddress ((const GLubyte*) functionName);
  94. #else
  95. static void* handle = dlopen (nullptr, RTLD_LAZY);
  96. return dlsym (handle, functionName);
  97. #endif
  98. }
  99. bool OpenGLHelpers::isExtensionSupported (const char* const extensionName)
  100. {
  101. jassert (extensionName != nullptr); // you must supply a genuine string for this.
  102. jassert (isContextActive()); // An OpenGL context will need to be active before calling this.
  103. if (getOpenGLVersion().major >= 3)
  104. {
  105. using GetStringi = const GLubyte* (*) (GLenum, GLuint);
  106. if (auto* thisGlGetStringi = reinterpret_cast<GetStringi> (getExtensionFunction ("glGetStringi")))
  107. {
  108. GLint n = 0;
  109. glGetIntegerv (GL_NUM_EXTENSIONS, &n);
  110. for (auto i = (decltype (n)) 0; i < n; ++i)
  111. if (StringRef (extensionName) == StringRef ((const char*) thisGlGetStringi (GL_EXTENSIONS, (GLuint) i)))
  112. return true;
  113. return false;
  114. }
  115. }
  116. const char* extensions = (const char*) glGetString (GL_EXTENSIONS);
  117. jassert (extensions != nullptr); // Perhaps you didn't activate an OpenGL context before calling this?
  118. for (;;)
  119. {
  120. const char* found = strstr (extensions, extensionName);
  121. if (found == nullptr)
  122. break;
  123. extensions = found + strlen (extensionName);
  124. if (extensions[0] == ' ' || extensions[0] == 0)
  125. return true;
  126. }
  127. return false;
  128. }
  129. void OpenGLHelpers::clear (Colour colour)
  130. {
  131. glClearColor (colour.getFloatRed(), colour.getFloatGreen(),
  132. colour.getFloatBlue(), colour.getFloatAlpha());
  133. glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  134. }
  135. void OpenGLHelpers::enableScissorTest (Rectangle<int> clip)
  136. {
  137. glEnable (GL_SCISSOR_TEST);
  138. glScissor (clip.getX(), clip.getY(), clip.getWidth(), clip.getHeight());
  139. }
  140. String OpenGLHelpers::getGLSLVersionString()
  141. {
  142. if (getOpenGLVersion() >= Version (3, 2))
  143. {
  144. #if JUCE_OPENGL_ES
  145. return "#version 300 es";
  146. #else
  147. return "#version 150";
  148. #endif
  149. }
  150. return "#version 110";
  151. }
  152. String OpenGLHelpers::translateVertexShaderToV3 (const String& code)
  153. {
  154. if (getOpenGLVersion() >= Version (3, 2))
  155. {
  156. String output;
  157. #if JUCE_ANDROID
  158. {
  159. int numAttributes = 0;
  160. for (int p = code.indexOf (0, "attribute "); p >= 0; p = code.indexOf (p + 1, "attribute "))
  161. numAttributes++;
  162. int last = 0;
  163. for (int p = code.indexOf (0, "attribute "); p >= 0; p = code.indexOf (p + 1, "attribute "))
  164. {
  165. output += code.substring (last, p) + "layout(location=" + String (--numAttributes) + ") in ";
  166. last = p + 10;
  167. }
  168. output += code.substring (last);
  169. }
  170. #else
  171. output = code.replace ("attribute", "in");
  172. #endif
  173. return getGLSLVersionString() + "\n" + output.replace ("varying", "out");
  174. }
  175. return code;
  176. }
  177. String OpenGLHelpers::translateFragmentShaderToV3 (const String& code)
  178. {
  179. if (getOpenGLVersion() >= Version (3, 2))
  180. return getGLSLVersionString() + "\n"
  181. "out " JUCE_MEDIUMP " vec4 fragColor;\n"
  182. + code.replace ("varying", "in")
  183. .replace ("texture2D", "texture")
  184. .replace ("gl_FragColor", "fragColor");
  185. return code;
  186. }
  187. } // namespace juce