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.

273 lines
11KB

  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. #ifndef __JUCE_OPENGLCOMPONENT_JUCEHEADER__
  19. #define __JUCE_OPENGLCOMPONENT_JUCEHEADER__
  20. #include "juce_OpenGLContext.h"
  21. #if JUCE_MAC && ! defined (DOXYGEN)
  22. typedef NSViewComponent OpenGLBaseType;
  23. #else
  24. typedef Component OpenGLBaseType;
  25. #endif
  26. //==============================================================================
  27. /**
  28. A component that contains an OpenGL canvas.
  29. Override this, add it to whatever component you want to, and use the renderOpenGL()
  30. method to draw its contents.
  31. */
  32. class JUCE_API OpenGLComponent : public OpenGLBaseType
  33. {
  34. public:
  35. //==============================================================================
  36. /** Used to select the type of openGL API to use, if more than one choice is available
  37. on a particular platform.
  38. */
  39. enum OpenGLType
  40. {
  41. openGLDefault = 0,
  42. #if JUCE_IOS
  43. openGLES1, /**< On the iPhone, this selects openGL ES 1.0 */
  44. openGLES2 /**< On the iPhone, this selects openGL ES 2.0 */
  45. #endif
  46. };
  47. /** Creates an OpenGLComponent.
  48. If useBackgroundThread is true, the component will launch a background thread
  49. to do the rendering. If false, then renderOpenGL() will be called as part of the
  50. normal paint() method.
  51. */
  52. OpenGLComponent (OpenGLType type = openGLDefault,
  53. bool useBackgroundThread = false);
  54. /** Destructor. */
  55. ~OpenGLComponent();
  56. //==============================================================================
  57. /** Changes the pixel format used by this component.
  58. @see OpenGLPixelFormat::getAvailablePixelFormats()
  59. */
  60. void setPixelFormat (const OpenGLPixelFormat& formatToUse);
  61. /** Returns the pixel format that this component is currently using. */
  62. OpenGLPixelFormat getPixelFormat() const;
  63. /** Specifies an OpenGL context which should be shared with the one that this
  64. component is using.
  65. This is an OpenGL feature that lets two contexts share their texture data.
  66. Note that this pointer is stored by the component, and when the component
  67. needs to recreate its internal context for some reason, the same context
  68. will be used again to share lists. So if you pass a context in here,
  69. don't delete the context while this component is still using it! You can
  70. call shareWith (nullptr) to stop this component from sharing with it.
  71. */
  72. void shareWith (OpenGLContext* contextToShareListsWith);
  73. /** Returns the context that this component is sharing with.
  74. @see shareWith
  75. */
  76. OpenGLContext* getShareContext() const noexcept { return contextToShareListsWith; }
  77. //==============================================================================
  78. /** Flips the openGL buffers over. */
  79. void swapBuffers();
  80. /** Returns true if the component is performing the rendering on a background thread.
  81. This property is specified in the constructor.
  82. */
  83. bool isUsingDedicatedThread() const noexcept { return useThread; }
  84. /** This replaces the normal paint() callback - use it to draw your openGL stuff.
  85. When this is called, makeCurrentContextActive() will already have been called
  86. for you, so you just need to draw.
  87. */
  88. virtual void renderOpenGL() = 0;
  89. /** This method is called when the component creates a new OpenGL context.
  90. A new context may be created when the component is first used, or when it
  91. is moved to a different window, or when the window is hidden and re-shown,
  92. etc.
  93. You can use this callback as an opportunity to set up things like textures
  94. that your context needs.
  95. New contexts are created on-demand by the makeCurrentContextActive() method - so
  96. if the context is deleted, e.g. by changing the pixel format or window, no context
  97. will be created until the next call to makeCurrentContextActive(), which will
  98. synchronously create one and call this method. This means that if you're using
  99. a non-GUI thread for rendering, you can make sure this method is be called by
  100. your renderer thread.
  101. When this callback happens, the context will already have been made current
  102. using the makeCurrentContextActive() method, so there's no need to call it
  103. again in your code.
  104. */
  105. virtual void newOpenGLContextCreated() = 0;
  106. /** This method is called when the component shuts down its OpenGL context.
  107. You can use this callback to delete textures and any other OpenGL objects you
  108. created in the component's context. Be aware: if you are using a render
  109. thread, this may be called on the thread.
  110. When this callback happens, the context will have been made current
  111. using the makeCurrentContextActive() method, so there's no need to call it
  112. again in your code.
  113. */
  114. virtual void releaseOpenGLContext() {}
  115. //==============================================================================
  116. /** Returns the context that will draw into this component.
  117. This may return 0 if the component is currently invisible or hasn't currently
  118. got a context. The context object can be deleted and a new one created during
  119. the lifetime of this component, and there may be times when it doesn't have one.
  120. @see newOpenGLContextCreated()
  121. */
  122. OpenGLContext* getCurrentContext() const noexcept { return context; }
  123. /** Makes this component the current openGL context.
  124. You might want to use this in things like your resize() method, before calling
  125. GL commands.
  126. If this returns false, then the context isn't active, so you should avoid
  127. making any calls.
  128. This call may actually create a context if one isn't currently initialised. If
  129. it does this, it will also synchronously call the newOpenGLContextCreated()
  130. method to let you initialise it as necessary.
  131. @see OpenGLContext::makeActive
  132. */
  133. bool makeCurrentContextActive();
  134. /** Stops the current component being the active OpenGL context.
  135. This is the opposite of makeCurrentContextActive()
  136. @see OpenGLContext::makeInactive
  137. */
  138. void makeCurrentContextInactive();
  139. /** Returns true if this component's context is the active openGL context for the
  140. current thread.
  141. @see OpenGLContext::isActive
  142. */
  143. bool isActiveContext() const noexcept;
  144. //==============================================================================
  145. /** Calls the rendering callback, and swaps the buffers afterwards.
  146. This is called automatically by paint() when the component needs to be rendered.
  147. Returns true if the operation succeeded.
  148. */
  149. virtual bool renderAndSwapBuffers();
  150. /** This returns a critical section that can be used to lock the current context.
  151. Because the context that is used by this component can change, e.g. when the
  152. component is shown or hidden, then if you're rendering to it on a background
  153. thread, this allows you to lock the context for the duration of your rendering
  154. routine.
  155. */
  156. CriticalSection& getContextLock() noexcept { return contextLock; }
  157. /** Delete the context.
  158. You should only need to call this if you've written a custom thread - if so, make
  159. sure that your thread calls this before it terminates.
  160. */
  161. void deleteContext();
  162. //==============================================================================
  163. /** Returns the native handle of an embedded heavyweight window, if there is one.
  164. E.g. On windows, this will return the HWND of the sub-window containing
  165. the opengl context, on the mac it'll be the NSOpenGLView.
  166. */
  167. void* getNativeWindowHandle() const;
  168. protected:
  169. /** Kicks off a thread to start rendering.
  170. The default implementation creates and manages an internal thread that tries
  171. to render at around 50fps, but this can be overloaded to create a custom thread.
  172. */
  173. virtual void startRenderThread();
  174. /** Cleans up the rendering thread.
  175. Used to shut down the thread that was started by startRenderThread(). If you've
  176. created a custom thread, then you should overload this to clean it up and delete it.
  177. */
  178. virtual void stopRenderThread();
  179. //==============================================================================
  180. /** @internal */
  181. void paint (Graphics& g);
  182. private:
  183. const OpenGLType type;
  184. class OpenGLComponentRenderThread;
  185. friend class OpenGLComponentRenderThread;
  186. friend class ScopedPointer <OpenGLComponentRenderThread>;
  187. ScopedPointer <OpenGLComponentRenderThread> renderThread;
  188. class OpenGLComponentWatcher;
  189. friend class OpenGLComponentWatcher;
  190. friend class ScopedPointer <OpenGLComponentWatcher>;
  191. ScopedPointer <OpenGLComponentWatcher> componentWatcher;
  192. ScopedPointer <OpenGLContext> context;
  193. OpenGLContext* contextToShareListsWith;
  194. CriticalSection contextLock;
  195. OpenGLPixelFormat preferredPixelFormat;
  196. bool needToUpdateViewport, needToDeleteContext, threadStarted;
  197. const bool useThread;
  198. OpenGLContext* createContext();
  199. void updateContext();
  200. void updateContextPosition();
  201. void stopBackgroundThread();
  202. void recreateContextAsync();
  203. void internalRepaint (int x, int y, int w, int h);
  204. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenGLComponent);
  205. };
  206. #endif // __JUCE_OPENGLCOMPONENT_JUCEHEADER__