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.

306 lines
8.3KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-7 by Raw Material Software ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the
  7. GNU General Public License, as published by the Free Software Foundation;
  8. either version 2 of the License, or (at your option) any later version.
  9. JUCE is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with JUCE; if not, visit www.gnu.org/licenses or write to the
  15. Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  16. Boston, MA 02111-1307 USA
  17. ------------------------------------------------------------------------------
  18. If you'd like to release a closed-source product which uses JUCE, commercial
  19. licenses are also available: visit www.rawmaterialsoftware.com/juce for
  20. more information.
  21. ==============================================================================
  22. */
  23. #include "../../../../juce_core/basics/juce_StandardHeader.h"
  24. #if JUCE_OPENGL
  25. BEGIN_JUCE_NAMESPACE
  26. #include "juce_OpenGLComponent.h"
  27. #include "../layout/juce_ComponentMovementWatcher.h"
  28. #include "../../../../juce_core/threads/juce_ScopedLock.h"
  29. //==============================================================================
  30. extern void juce_glViewport (const int w, const int h);
  31. //==============================================================================
  32. OpenGLPixelFormat::OpenGLPixelFormat (const int bitsPerRGBComponent,
  33. const int alphaBits_,
  34. const int depthBufferBits_,
  35. const int stencilBufferBits_) throw()
  36. : redBits (bitsPerRGBComponent),
  37. greenBits (bitsPerRGBComponent),
  38. blueBits (bitsPerRGBComponent),
  39. alphaBits (alphaBits_),
  40. depthBufferBits (depthBufferBits_),
  41. stencilBufferBits (stencilBufferBits_),
  42. accumulationBufferRedBits (0),
  43. accumulationBufferGreenBits (0),
  44. accumulationBufferBlueBits (0),
  45. accumulationBufferAlphaBits (0),
  46. fullSceneAntiAliasingNumSamples (0)
  47. {
  48. }
  49. bool OpenGLPixelFormat::operator== (const OpenGLPixelFormat& other) const throw()
  50. {
  51. return memcmp (this, &other, sizeof (other)) == 0;
  52. }
  53. //==============================================================================
  54. static VoidArray knownContexts;
  55. OpenGLContext::OpenGLContext() throw()
  56. {
  57. knownContexts.add (this);
  58. }
  59. OpenGLContext::~OpenGLContext()
  60. {
  61. knownContexts.removeValue (this);
  62. }
  63. OpenGLContext* OpenGLContext::getCurrentContext()
  64. {
  65. for (int i = knownContexts.size(); --i >= 0;)
  66. {
  67. OpenGLContext* const oglc = (OpenGLContext*) knownContexts.getUnchecked(i);
  68. if (oglc->isActive())
  69. return oglc;
  70. }
  71. return 0;
  72. }
  73. //==============================================================================
  74. class OpenGLComponentWatcher : public ComponentMovementWatcher
  75. {
  76. public:
  77. //==============================================================================
  78. OpenGLComponentWatcher (OpenGLComponent* const owner_)
  79. : ComponentMovementWatcher (owner_),
  80. owner (owner_),
  81. wasShowing (false)
  82. {
  83. }
  84. ~OpenGLComponentWatcher() {}
  85. //==============================================================================
  86. void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/)
  87. {
  88. owner->updateContextPosition();
  89. }
  90. void componentPeerChanged()
  91. {
  92. const ScopedLock sl (owner->getContextLock());
  93. owner->deleteContext();
  94. }
  95. void componentVisibilityChanged (Component&)
  96. {
  97. const bool isShowingNow = owner->isShowing();
  98. if (wasShowing != isShowingNow)
  99. {
  100. wasShowing = isShowingNow;
  101. owner->updateContextPosition();
  102. }
  103. }
  104. //==============================================================================
  105. juce_UseDebuggingNewOperator
  106. private:
  107. OpenGLComponent* const owner;
  108. bool wasShowing;
  109. };
  110. //==============================================================================
  111. OpenGLComponent::OpenGLComponent()
  112. : context (0),
  113. contextToShareListsWith (0),
  114. needToUpdateViewport (true)
  115. {
  116. setOpaque (true);
  117. componentWatcher = new OpenGLComponentWatcher (this);
  118. }
  119. OpenGLComponent::~OpenGLComponent()
  120. {
  121. deleteContext();
  122. delete componentWatcher;
  123. }
  124. void OpenGLComponent::deleteContext()
  125. {
  126. const ScopedLock sl (contextLock);
  127. deleteAndZero (context);
  128. }
  129. void OpenGLComponent::updateContextPosition()
  130. {
  131. needToUpdateViewport = true;
  132. if (getWidth() > 0 && getHeight() > 0)
  133. {
  134. Component* const topComp = getTopLevelComponent();
  135. if (topComp->getPeer() != 0)
  136. {
  137. const ScopedLock sl (contextLock);
  138. if (context != 0)
  139. context->updateWindowPosition (getScreenX() - topComp->getScreenX(),
  140. getScreenY() - topComp->getScreenY(),
  141. getWidth(),
  142. getHeight(),
  143. topComp->getHeight());
  144. }
  145. }
  146. }
  147. const OpenGLPixelFormat OpenGLComponent::getPixelFormat() const
  148. {
  149. OpenGLPixelFormat pf;
  150. const ScopedLock sl (contextLock);
  151. if (context != 0)
  152. pf = context->getPixelFormat();
  153. return pf;
  154. }
  155. void OpenGLComponent::setPixelFormat (const OpenGLPixelFormat& formatToUse)
  156. {
  157. if (! (preferredPixelFormat == formatToUse))
  158. {
  159. const ScopedLock sl (contextLock);
  160. deleteContext();
  161. preferredPixelFormat = formatToUse;
  162. }
  163. }
  164. void OpenGLComponent::shareWith (OpenGLContext* context)
  165. {
  166. if (contextToShareListsWith != context)
  167. {
  168. const ScopedLock sl (contextLock);
  169. deleteContext();
  170. contextToShareListsWith = context;
  171. }
  172. }
  173. bool OpenGLComponent::makeCurrentContextActive()
  174. {
  175. if (context == 0)
  176. {
  177. const ScopedLock sl (contextLock);
  178. if (isShowing() && getTopLevelComponent()->getPeer() != 0)
  179. {
  180. context = OpenGLContext::createContextForWindow (this,
  181. preferredPixelFormat,
  182. contextToShareListsWith);
  183. if (context != 0)
  184. {
  185. updateContextPosition();
  186. if (context->makeActive())
  187. newOpenGLContextCreated();
  188. }
  189. }
  190. }
  191. return context != 0 && context->makeActive();
  192. }
  193. void OpenGLComponent::makeCurrentContextInactive()
  194. {
  195. if (context != 0)
  196. context->makeInactive();
  197. }
  198. bool OpenGLComponent::isActiveContext() const throw()
  199. {
  200. return context != 0 && context->isActive();
  201. }
  202. void OpenGLComponent::swapBuffers()
  203. {
  204. if (context != 0)
  205. context->swapBuffers();
  206. }
  207. void OpenGLComponent::paint (Graphics&)
  208. {
  209. if (renderAndSwapBuffers())
  210. {
  211. ComponentPeer* const peer = getPeer();
  212. if (peer != 0)
  213. {
  214. peer->addMaskedRegion (getScreenX() - peer->getScreenX(),
  215. getScreenY() - peer->getScreenY(),
  216. getWidth(), getHeight());
  217. }
  218. }
  219. }
  220. bool OpenGLComponent::renderAndSwapBuffers()
  221. {
  222. const ScopedLock sl (contextLock);
  223. if (! makeCurrentContextActive())
  224. return false;
  225. if (needToUpdateViewport)
  226. {
  227. needToUpdateViewport = false;
  228. juce_glViewport (getWidth(), getHeight());
  229. }
  230. renderOpenGL();
  231. swapBuffers();
  232. return true;
  233. }
  234. void OpenGLComponent::internalRepaint (int x, int y, int w, int h)
  235. {
  236. Component::internalRepaint (x, y, w, h);
  237. if (context != 0)
  238. context->repaint();
  239. }
  240. END_JUCE_NAMESPACE
  241. #endif