| @@ -2948,6 +2948,18 @@ public: | |||
| glXSwapBuffers (display, embeddedWindow); | |||
| } | |||
| bool setSwapInterval (const int numFramesPerSwap) | |||
| { | |||
| // xxx needs doing.. | |||
| return false; | |||
| } | |||
| int getSwapInterval() const | |||
| { | |||
| // xxx needs doing.. | |||
| return 0; | |||
| } | |||
| void repaint() | |||
| { | |||
| } | |||
| @@ -3401,6 +3401,18 @@ public: | |||
| aglSwapBuffers (renderContext); | |||
| } | |||
| bool setSwapInterval (const int numFramesPerSwap) | |||
| { | |||
| return aglSetInteger (renderContext, AGL_SWAP_INTERVAL, &numFramesPerSwap); | |||
| } | |||
| int getSwapInterval() const | |||
| { | |||
| GLint numFrames = 0; | |||
| aglGetInteger (renderContext, AGL_SWAP_INTERVAL, &numFrames); | |||
| return numFrames; | |||
| } | |||
| void repaint() | |||
| { | |||
| } | |||
| @@ -3037,6 +3037,8 @@ bool DragAndDropContainer::performExternalDragDropOfText (const String& text) | |||
| typedef const char* (WINAPI* PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); | |||
| typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); | |||
| typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int* piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); | |||
| typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); | |||
| typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); | |||
| #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 | |||
| #define WGL_DRAW_TO_WINDOW_ARB 0x2001 | |||
| @@ -3299,6 +3301,32 @@ public: | |||
| SwapBuffers (dc); | |||
| } | |||
| bool setSwapInterval (const int numFramesPerSwap) | |||
| { | |||
| StringArray availableExtensions; | |||
| getWglExtensions (dc, availableExtensions); | |||
| PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = 0; | |||
| return availableExtensions.contains ("WGL_EXT_swap_control") | |||
| && WGL_EXT_FUNCTION_INIT (PFNWGLSWAPINTERVALEXTPROC, wglSwapIntervalEXT) | |||
| && wglSwapIntervalEXT (numFramesPerSwap) != FALSE; | |||
| } | |||
| int getSwapInterval() const | |||
| { | |||
| StringArray availableExtensions; | |||
| getWglExtensions (dc, availableExtensions); | |||
| PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT = 0; | |||
| if (availableExtensions.contains ("WGL_EXT_swap_control") | |||
| && WGL_EXT_FUNCTION_INIT (PFNWGLGETSWAPINTERVALEXTPROC, wglGetSwapIntervalEXT)) | |||
| return wglGetSwapIntervalEXT(); | |||
| return 0; | |||
| } | |||
| void findAlternativeOpenGLPixelFormats (OwnedArray <OpenGLPixelFormat>& results) | |||
| { | |||
| jassert (isActive()); | |||
| @@ -93,7 +93,6 @@ public: | |||
| { | |||
| const ScopedLock sl (owner->getContextLock()); | |||
| owner->deleteContext(); | |||
| owner->createContext(); | |||
| } | |||
| void componentVisibilityChanged (Component&) | |||
| @@ -131,30 +130,6 @@ OpenGLComponent::~OpenGLComponent() | |||
| delete componentWatcher; | |||
| } | |||
| void OpenGLComponent::createContext() | |||
| { | |||
| const ScopedLock sl (contextLock); | |||
| jassert (context == 0); | |||
| if (context == 0 && isShowing() && getTopLevelComponent()->getPeer() != 0) | |||
| { | |||
| context = OpenGLContext::createContextForWindow (this, | |||
| preferredPixelFormat, | |||
| componentToShareListsWith != 0 | |||
| ? componentToShareListsWith->context | |||
| : 0); | |||
| if (context != 0) | |||
| { | |||
| updateContextPosition(); | |||
| if (makeCurrentContextActive()) | |||
| newOpenGLContextCreated(); | |||
| } | |||
| } | |||
| } | |||
| void OpenGLComponent::deleteContext() | |||
| { | |||
| const ScopedLock sl (contextLock); | |||
| @@ -173,9 +148,6 @@ void OpenGLComponent::updateContextPosition() | |||
| { | |||
| const ScopedLock sl (contextLock); | |||
| if (context == 0) | |||
| createContext(); | |||
| if (context != 0) | |||
| context->updateWindowPosition (getScreenX() - topComp->getScreenX(), | |||
| getScreenY() - topComp->getScreenY(), | |||
| @@ -197,17 +169,14 @@ const OpenGLPixelFormat OpenGLComponent::getPixelFormat() const | |||
| return pf; | |||
| } | |||
| bool OpenGLComponent::setPixelFormat (const OpenGLPixelFormat& formatToUse) | |||
| void OpenGLComponent::setPixelFormat (const OpenGLPixelFormat& formatToUse) | |||
| { | |||
| if (preferredPixelFormat == formatToUse) | |||
| return true; | |||
| const ScopedLock sl (contextLock); | |||
| deleteContext(); | |||
| preferredPixelFormat = formatToUse; | |||
| createContext(); | |||
| return context != 0; | |||
| if (! (preferredPixelFormat == formatToUse)) | |||
| { | |||
| const ScopedLock sl (contextLock); | |||
| deleteContext(); | |||
| preferredPixelFormat = formatToUse; | |||
| } | |||
| } | |||
| void OpenGLComponent::shareWith (OpenGLComponent* const comp) | |||
| @@ -217,12 +186,33 @@ void OpenGLComponent::shareWith (OpenGLComponent* const comp) | |||
| const ScopedLock sl (contextLock); | |||
| deleteContext(); | |||
| componentToShareListsWith = comp; | |||
| createContext(); | |||
| } | |||
| } | |||
| bool OpenGLComponent::makeCurrentContextActive() | |||
| { | |||
| if (context == 0) | |||
| { | |||
| const ScopedLock sl (contextLock); | |||
| if (isShowing() && getTopLevelComponent()->getPeer() != 0) | |||
| { | |||
| context = OpenGLContext::createContextForWindow (this, | |||
| preferredPixelFormat, | |||
| componentToShareListsWith != 0 | |||
| ? componentToShareListsWith->context | |||
| : 0); | |||
| if (context != 0) | |||
| { | |||
| updateContextPosition(); | |||
| if (context->makeActive()) | |||
| newOpenGLContextCreated(); | |||
| } | |||
| } | |||
| } | |||
| return context != 0 && context->makeActive(); | |||
| } | |||
| @@ -110,6 +110,21 @@ public: | |||
| /** Swaps the buffers (if the context can do this). */ | |||
| virtual void swapBuffers() = 0; | |||
| /** Sets whether the context checks the vertical sync before swapping. | |||
| The value is the number of frames to allow between buffer-swapping. This is | |||
| fairly system-dependent, but 0 turns off syncing, 1 makes it swap on frame-boundaries, | |||
| and greater numbers indicate that it should swap less often. | |||
| Returns true if it sets the value successfully. | |||
| */ | |||
| virtual bool setSwapInterval (const int numFramesPerSwap) = 0; | |||
| /** Returns the current swap-sync interval. | |||
| See setSwapInterval() for info about the value returned. | |||
| */ | |||
| virtual int getSwapInterval() const = 0; | |||
| //============================================================================== | |||
| /** Returns the pixel format being used by this context. */ | |||
| virtual const OpenGLPixelFormat getPixelFormat() const = 0; | |||
| @@ -175,7 +190,7 @@ public: | |||
| @see OpenGLPixelFormat::getAvailablePixelFormats() | |||
| */ | |||
| bool setPixelFormat (const OpenGLPixelFormat& formatToUse); | |||
| void setPixelFormat (const OpenGLPixelFormat& formatToUse); | |||
| /** Returns the pixel format that this component is currently using. */ | |||
| const OpenGLPixelFormat getPixelFormat() const; | |||
| @@ -207,6 +222,13 @@ public: | |||
| You can use this callback as an opportunity to set up things like textures | |||
| that your context needs. | |||
| New contexts are created on-demand by the makeCurrentContextActive() method - so | |||
| if the context is deleted, e.g. by changing the pixel format or window, no context | |||
| will be created until the next call to makeCurrentContextActive(), which will | |||
| synchronously create one and call this method. This means that if you're using | |||
| a non-GUI thread for rendering, you can make sure this method is be called by | |||
| your renderer thread. | |||
| When this callback happens, the context will already have been made current | |||
| using the makeCurrentContextActive() method, so there's no need to call it | |||
| again in your code. | |||
| @@ -217,9 +239,11 @@ public: | |||
| //============================================================================== | |||
| /** Returns the context that will draw into this component. | |||
| This may return 0 if it failed to initialise properly, or if the component | |||
| is currently invisible. The context object may be deleted and a new one created | |||
| during the life of this component - see newOpenGLContextCreated(). | |||
| This may return 0 if the component is currently invisible or hasn't currently | |||
| got a context. The context object can be deleted and a new one created during | |||
| the lifetime of this component, and there may be times when it doesn't have one. | |||
| @see newOpenGLContextCreated() | |||
| */ | |||
| OpenGLContext* getCurrentContext() const throw(); | |||
| @@ -231,6 +255,10 @@ public: | |||
| If this returns false, then the context isn't active, so you should avoid | |||
| making any calls. | |||
| This call may actually create a context if one isn't currently initialised. If | |||
| it does this, it will also synchronously call the newOpenGLContextCreated() | |||
| method to let you initialise it as necessary. | |||
| @see OpenGLContext::makeActive | |||
| */ | |||
| bool makeCurrentContextActive(); | |||
| @@ -289,7 +317,6 @@ private: | |||
| OpenGLPixelFormat preferredPixelFormat; | |||
| bool needToUpdateViewport; | |||
| void createContext(); | |||
| void deleteContext(); | |||
| void updateContextPosition(); | |||
| void internalRepaint (int x, int y, int w, int h); | |||