|
- /*
- ==============================================================================
-
- This file is part of the JUCE library - "Jules' Utility Class Extensions"
- Copyright 2004-7 by Raw Material Software ltd.
-
- ------------------------------------------------------------------------------
-
- JUCE can be redistributed and/or modified under the terms of the
- GNU General Public License, as published by the Free Software Foundation;
- either version 2 of the License, or (at your option) any later version.
-
- JUCE is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with JUCE; if not, visit www.gnu.org/licenses or write to the
- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- Boston, MA 02111-1307 USA
-
- ------------------------------------------------------------------------------
-
- If you'd like to release a closed-source product which uses JUCE, commercial
- licenses are also available: visit www.rawmaterialsoftware.com/juce for
- more information.
-
- ==============================================================================
- */
-
- #include "../../../../juce_core/basics/juce_StandardHeader.h"
-
- #if JUCE_OPENGL
-
- BEGIN_JUCE_NAMESPACE
-
- #include "juce_OpenGLComponent.h"
- #include "../layout/juce_ComponentMovementWatcher.h"
- #include "../../../../juce_core/threads/juce_ScopedLock.h"
-
-
- //==============================================================================
- extern void juce_glViewport (const int w, const int h);
-
-
- //==============================================================================
- OpenGLPixelFormat::OpenGLPixelFormat (const int bitsPerRGBComponent,
- const int alphaBits_,
- const int depthBufferBits_,
- const int stencilBufferBits_) throw()
- : redBits (bitsPerRGBComponent),
- greenBits (bitsPerRGBComponent),
- blueBits (bitsPerRGBComponent),
- alphaBits (alphaBits_),
- depthBufferBits (depthBufferBits_),
- stencilBufferBits (stencilBufferBits_),
- accumulationBufferRedBits (0),
- accumulationBufferGreenBits (0),
- accumulationBufferBlueBits (0),
- accumulationBufferAlphaBits (0),
- fullSceneAntiAliasingNumSamples (0)
- {
- }
-
- bool OpenGLPixelFormat::operator== (const OpenGLPixelFormat& other) const throw()
- {
- return memcmp (this, &other, sizeof (other)) == 0;
- }
-
- //==============================================================================
- static VoidArray knownContexts;
-
- OpenGLContext::OpenGLContext() throw()
- {
- knownContexts.add (this);
- }
-
- OpenGLContext::~OpenGLContext()
- {
- knownContexts.removeValue (this);
- }
-
- OpenGLContext* OpenGLContext::getCurrentContext()
- {
- for (int i = knownContexts.size(); --i >= 0;)
- {
- OpenGLContext* const oglc = (OpenGLContext*) knownContexts.getUnchecked(i);
-
- if (oglc->isActive())
- return oglc;
- }
-
- return 0;
- }
-
-
- //==============================================================================
- class OpenGLComponentWatcher : public ComponentMovementWatcher
- {
- public:
- //==============================================================================
- OpenGLComponentWatcher (OpenGLComponent* const owner_)
- : ComponentMovementWatcher (owner_),
- owner (owner_),
- wasShowing (false)
- {
- }
-
- ~OpenGLComponentWatcher() {}
-
- //==============================================================================
- void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/)
- {
- owner->updateContextPosition();
- }
-
- void componentPeerChanged()
- {
- const ScopedLock sl (owner->getContextLock());
- owner->deleteContext();
- }
-
- void componentVisibilityChanged (Component&)
- {
- const bool isShowingNow = owner->isShowing();
-
- if (wasShowing != isShowingNow)
- {
- wasShowing = isShowingNow;
- owner->updateContextPosition();
- }
- }
-
- //==============================================================================
- juce_UseDebuggingNewOperator
-
- private:
- OpenGLComponent* const owner;
- bool wasShowing;
- };
-
- //==============================================================================
- OpenGLComponent::OpenGLComponent()
- : context (0),
- contextToShareListsWith (0),
- needToUpdateViewport (true)
- {
- setOpaque (true);
- componentWatcher = new OpenGLComponentWatcher (this);
- }
-
- OpenGLComponent::~OpenGLComponent()
- {
- deleteContext();
- delete componentWatcher;
- }
-
- void OpenGLComponent::deleteContext()
- {
- const ScopedLock sl (contextLock);
- deleteAndZero (context);
- }
-
- void OpenGLComponent::updateContextPosition()
- {
- needToUpdateViewport = true;
-
- if (getWidth() > 0 && getHeight() > 0)
- {
- Component* const topComp = getTopLevelComponent();
-
- if (topComp->getPeer() != 0)
- {
- const ScopedLock sl (contextLock);
-
- if (context != 0)
- context->updateWindowPosition (getScreenX() - topComp->getScreenX(),
- getScreenY() - topComp->getScreenY(),
- getWidth(),
- getHeight(),
- topComp->getHeight());
- }
- }
- }
-
- const OpenGLPixelFormat OpenGLComponent::getPixelFormat() const
- {
- OpenGLPixelFormat pf;
-
- const ScopedLock sl (contextLock);
- if (context != 0)
- pf = context->getPixelFormat();
-
- return pf;
- }
-
- void OpenGLComponent::setPixelFormat (const OpenGLPixelFormat& formatToUse)
- {
- if (! (preferredPixelFormat == formatToUse))
- {
- const ScopedLock sl (contextLock);
- deleteContext();
- preferredPixelFormat = formatToUse;
- }
- }
-
- void OpenGLComponent::shareWith (OpenGLContext* context)
- {
- if (contextToShareListsWith != context)
- {
- const ScopedLock sl (contextLock);
- deleteContext();
- contextToShareListsWith = context;
- }
- }
-
- bool OpenGLComponent::makeCurrentContextActive()
- {
- if (context == 0)
- {
- const ScopedLock sl (contextLock);
-
- if (isShowing() && getTopLevelComponent()->getPeer() != 0)
- {
- context = OpenGLContext::createContextForWindow (this,
- preferredPixelFormat,
- contextToShareListsWith);
-
- if (context != 0)
- {
- updateContextPosition();
-
- if (context->makeActive())
- newOpenGLContextCreated();
- }
- }
- }
-
- return context != 0 && context->makeActive();
- }
-
- void OpenGLComponent::makeCurrentContextInactive()
- {
- if (context != 0)
- context->makeInactive();
- }
-
- bool OpenGLComponent::isActiveContext() const throw()
- {
- return context != 0 && context->isActive();
- }
-
- void OpenGLComponent::swapBuffers()
- {
- if (context != 0)
- context->swapBuffers();
- }
-
- void OpenGLComponent::paint (Graphics&)
- {
- if (renderAndSwapBuffers())
- {
- ComponentPeer* const peer = getPeer();
-
- if (peer != 0)
- {
- peer->addMaskedRegion (getScreenX() - peer->getScreenX(),
- getScreenY() - peer->getScreenY(),
- getWidth(), getHeight());
- }
- }
- }
-
- bool OpenGLComponent::renderAndSwapBuffers()
- {
- const ScopedLock sl (contextLock);
-
- if (! makeCurrentContextActive())
- return false;
-
- if (needToUpdateViewport)
- {
- needToUpdateViewport = false;
- juce_glViewport (getWidth(), getHeight());
- }
-
- renderOpenGL();
- swapBuffers();
-
- return true;
- }
-
- void OpenGLComponent::internalRepaint (int x, int y, int w, int h)
- {
- Component::internalRepaint (x, y, w, h);
-
- if (context != 0)
- context->repaint();
- }
-
-
- END_JUCE_NAMESPACE
-
- #endif
|