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.

244 lines
7.9KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. END_JUCE_NAMESPACE
  19. @interface JuceGLView : UIView
  20. {
  21. }
  22. + (Class) layerClass;
  23. @end
  24. @implementation JuceGLView
  25. + (Class) layerClass
  26. {
  27. return [CAEAGLLayer class];
  28. }
  29. @end
  30. BEGIN_JUCE_NAMESPACE
  31. //==============================================================================
  32. class GLESContext : public OpenGLContext
  33. {
  34. public:
  35. GLESContext (UIView* parentView,
  36. Component* const component_,
  37. const OpenGLPixelFormat& pixelFormat_,
  38. const GLESContext* const sharedContext,
  39. NSUInteger apiType)
  40. : component (component_), pixelFormat (pixelFormat_), glLayer (nil), context (nil),
  41. useDepthBuffer (pixelFormat_.depthBufferBits > 0), frameBufferHandle (0), colorBufferHandle (0),
  42. depthBufferHandle (0), lastWidth (0), lastHeight (0)
  43. {
  44. view = [[JuceGLView alloc] initWithFrame: CGRectMake (0, 0, 64, 64)];
  45. view.opaque = YES;
  46. view.hidden = NO;
  47. view.backgroundColor = [UIColor blackColor];
  48. view.userInteractionEnabled = NO;
  49. glLayer = (CAEAGLLayer*) [view layer];
  50. [parentView addSubview: view];
  51. if (sharedContext != nullptr)
  52. context = [[EAGLContext alloc] initWithAPI: apiType
  53. sharegroup: [sharedContext->context sharegroup]];
  54. else
  55. context = [[EAGLContext alloc] initWithAPI: apiType];
  56. createGLBuffers();
  57. }
  58. ~GLESContext()
  59. {
  60. deleteContext();
  61. [view removeFromSuperview];
  62. [view release];
  63. freeGLBuffers();
  64. }
  65. void deleteContext()
  66. {
  67. makeInactive();
  68. [context release];
  69. context = nil;
  70. }
  71. bool makeActive() const noexcept
  72. {
  73. jassert (context != nil);
  74. [EAGLContext setCurrentContext: context];
  75. glBindFramebufferOES (GL_FRAMEBUFFER_OES, frameBufferHandle);
  76. return true;
  77. }
  78. void swapBuffers()
  79. {
  80. glBindRenderbufferOES (GL_RENDERBUFFER_OES, colorBufferHandle);
  81. [context presentRenderbuffer: GL_RENDERBUFFER_OES];
  82. }
  83. bool makeInactive() const noexcept
  84. {
  85. return [EAGLContext setCurrentContext: nil];
  86. }
  87. bool isActive() const noexcept
  88. {
  89. return [EAGLContext currentContext] == context;
  90. }
  91. OpenGLPixelFormat getPixelFormat() const { return pixelFormat; }
  92. void* getRawContext() const noexcept { return glLayer; }
  93. unsigned int getFrameBufferID() const { return (unsigned int) frameBufferHandle; }
  94. void updateWindowPosition (const Rectangle<int>& bounds)
  95. {
  96. // For some strange reason, the view seems to fail unless its width is a multiple of 8...
  97. view.frame = CGRectMake ((CGFloat) bounds.getX(), (CGFloat) bounds.getY(),
  98. (CGFloat) (bounds.getWidth() & ~7),
  99. (CGFloat) bounds.getHeight());
  100. if (lastWidth != bounds.getWidth() || lastHeight != bounds.getHeight())
  101. {
  102. lastWidth = bounds.getWidth();
  103. lastHeight = bounds.getHeight();
  104. freeGLBuffers();
  105. createGLBuffers();
  106. }
  107. }
  108. bool setSwapInterval (const int numFramesPerSwap)
  109. {
  110. numFrames = numFramesPerSwap;
  111. return true;
  112. }
  113. int getSwapInterval() const
  114. {
  115. return numFrames;
  116. }
  117. void repaint()
  118. {
  119. }
  120. //==============================================================================
  121. void createGLBuffers()
  122. {
  123. makeActive();
  124. glGenFramebuffersOES (1, &frameBufferHandle);
  125. glGenRenderbuffersOES (1, &colorBufferHandle);
  126. glGenRenderbuffersOES (1, &depthBufferHandle);
  127. glBindRenderbufferOES (GL_RENDERBUFFER_OES, colorBufferHandle);
  128. [context renderbufferStorage: GL_RENDERBUFFER_OES fromDrawable: glLayer];
  129. GLint width, height;
  130. glGetRenderbufferParameterivOES (GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &width);
  131. glGetRenderbufferParameterivOES (GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &height);
  132. if (useDepthBuffer)
  133. {
  134. glBindRenderbufferOES (GL_RENDERBUFFER_OES, depthBufferHandle);
  135. glRenderbufferStorageOES (GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, width, height);
  136. }
  137. glBindRenderbufferOES (GL_RENDERBUFFER_OES, colorBufferHandle);
  138. glBindFramebufferOES (GL_FRAMEBUFFER_OES, frameBufferHandle);
  139. glFramebufferRenderbufferOES (GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorBufferHandle);
  140. if (useDepthBuffer)
  141. glFramebufferRenderbufferOES (GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthBufferHandle);
  142. jassert (glCheckFramebufferStatusOES (GL_FRAMEBUFFER_OES) == GL_FRAMEBUFFER_COMPLETE_OES);
  143. }
  144. void freeGLBuffers()
  145. {
  146. if (frameBufferHandle != 0)
  147. {
  148. glDeleteFramebuffersOES (1, &frameBufferHandle);
  149. frameBufferHandle = 0;
  150. }
  151. if (colorBufferHandle != 0)
  152. {
  153. glDeleteRenderbuffersOES (1, &colorBufferHandle);
  154. colorBufferHandle = 0;
  155. }
  156. if (depthBufferHandle != 0)
  157. {
  158. glDeleteRenderbuffersOES (1, &depthBufferHandle);
  159. depthBufferHandle = 0;
  160. }
  161. }
  162. //==============================================================================
  163. private:
  164. WeakReference<Component> component;
  165. OpenGLPixelFormat pixelFormat;
  166. JuceGLView* view;
  167. CAEAGLLayer* glLayer;
  168. EAGLContext* context;
  169. bool useDepthBuffer;
  170. GLuint frameBufferHandle, colorBufferHandle, depthBufferHandle;
  171. int numFrames;
  172. int lastWidth, lastHeight;
  173. //==============================================================================
  174. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GLESContext);
  175. };
  176. OpenGLContext* OpenGLComponent::createContext()
  177. {
  178. JUCE_AUTORELEASEPOOL
  179. ComponentPeer* peer = getPeer();
  180. if (peer != nullptr)
  181. return new GLESContext ((UIView*) peer->getNativeHandle(), this, preferredPixelFormat,
  182. dynamic_cast <const GLESContext*> (contextToShareListsWith),
  183. type == openGLES2 ? kEAGLRenderingAPIOpenGLES2 : kEAGLRenderingAPIOpenGLES1);
  184. return nullptr;
  185. }
  186. void OpenGLPixelFormat::getAvailablePixelFormats (Component* /*component*/,
  187. OwnedArray <OpenGLPixelFormat>& /*results*/)
  188. {
  189. }
  190. //==============================================================================
  191. bool OpenGLHelpers::isContextActive()
  192. {
  193. return [EAGLContext currentContext] != nil;
  194. }