| @@ -2948,6 +2948,18 @@ public: | |||||
| glXSwapBuffers (display, embeddedWindow); | glXSwapBuffers (display, embeddedWindow); | ||||
| } | } | ||||
| bool setSwapInterval (const int numFramesPerSwap) | |||||
| { | |||||
| // xxx needs doing.. | |||||
| return false; | |||||
| } | |||||
| int getSwapInterval() const | |||||
| { | |||||
| // xxx needs doing.. | |||||
| return 0; | |||||
| } | |||||
| void repaint() | void repaint() | ||||
| { | { | ||||
| } | } | ||||
| @@ -3401,6 +3401,18 @@ public: | |||||
| aglSwapBuffers (renderContext); | 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() | void repaint() | ||||
| { | { | ||||
| } | } | ||||
| @@ -3037,6 +3037,8 @@ bool DragAndDropContainer::performExternalDragDropOfText (const String& text) | |||||
| typedef const char* (WINAPI* PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); | 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 * 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 * 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_NUMBER_PIXEL_FORMATS_ARB 0x2000 | ||||
| #define WGL_DRAW_TO_WINDOW_ARB 0x2001 | #define WGL_DRAW_TO_WINDOW_ARB 0x2001 | ||||
| @@ -3299,6 +3301,32 @@ public: | |||||
| SwapBuffers (dc); | 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) | void findAlternativeOpenGLPixelFormats (OwnedArray <OpenGLPixelFormat>& results) | ||||
| { | { | ||||
| jassert (isActive()); | jassert (isActive()); | ||||
| @@ -93,7 +93,6 @@ public: | |||||
| { | { | ||||
| const ScopedLock sl (owner->getContextLock()); | const ScopedLock sl (owner->getContextLock()); | ||||
| owner->deleteContext(); | owner->deleteContext(); | ||||
| owner->createContext(); | |||||
| } | } | ||||
| void componentVisibilityChanged (Component&) | void componentVisibilityChanged (Component&) | ||||
| @@ -131,30 +130,6 @@ OpenGLComponent::~OpenGLComponent() | |||||
| delete componentWatcher; | 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() | void OpenGLComponent::deleteContext() | ||||
| { | { | ||||
| const ScopedLock sl (contextLock); | const ScopedLock sl (contextLock); | ||||
| @@ -173,9 +148,6 @@ void OpenGLComponent::updateContextPosition() | |||||
| { | { | ||||
| const ScopedLock sl (contextLock); | const ScopedLock sl (contextLock); | ||||
| if (context == 0) | |||||
| createContext(); | |||||
| if (context != 0) | if (context != 0) | ||||
| context->updateWindowPosition (getScreenX() - topComp->getScreenX(), | context->updateWindowPosition (getScreenX() - topComp->getScreenX(), | ||||
| getScreenY() - topComp->getScreenY(), | getScreenY() - topComp->getScreenY(), | ||||
| @@ -197,17 +169,14 @@ const OpenGLPixelFormat OpenGLComponent::getPixelFormat() const | |||||
| return pf; | 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) | void OpenGLComponent::shareWith (OpenGLComponent* const comp) | ||||
| @@ -217,12 +186,33 @@ void OpenGLComponent::shareWith (OpenGLComponent* const comp) | |||||
| const ScopedLock sl (contextLock); | const ScopedLock sl (contextLock); | ||||
| deleteContext(); | deleteContext(); | ||||
| componentToShareListsWith = comp; | componentToShareListsWith = comp; | ||||
| createContext(); | |||||
| } | } | ||||
| } | } | ||||
| bool OpenGLComponent::makeCurrentContextActive() | 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(); | return context != 0 && context->makeActive(); | ||||
| } | } | ||||
| @@ -110,6 +110,21 @@ public: | |||||
| /** Swaps the buffers (if the context can do this). */ | /** Swaps the buffers (if the context can do this). */ | ||||
| virtual void swapBuffers() = 0; | 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. */ | /** Returns the pixel format being used by this context. */ | ||||
| virtual const OpenGLPixelFormat getPixelFormat() const = 0; | virtual const OpenGLPixelFormat getPixelFormat() const = 0; | ||||
| @@ -175,7 +190,7 @@ public: | |||||
| @see OpenGLPixelFormat::getAvailablePixelFormats() | @see OpenGLPixelFormat::getAvailablePixelFormats() | ||||
| */ | */ | ||||
| bool setPixelFormat (const OpenGLPixelFormat& formatToUse); | |||||
| void setPixelFormat (const OpenGLPixelFormat& formatToUse); | |||||
| /** Returns the pixel format that this component is currently using. */ | /** Returns the pixel format that this component is currently using. */ | ||||
| const OpenGLPixelFormat getPixelFormat() const; | const OpenGLPixelFormat getPixelFormat() const; | ||||
| @@ -207,6 +222,13 @@ public: | |||||
| You can use this callback as an opportunity to set up things like textures | You can use this callback as an opportunity to set up things like textures | ||||
| that your context needs. | 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 | When this callback happens, the context will already have been made current | ||||
| using the makeCurrentContextActive() method, so there's no need to call it | using the makeCurrentContextActive() method, so there's no need to call it | ||||
| again in your code. | again in your code. | ||||
| @@ -217,9 +239,11 @@ public: | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Returns the context that will draw into this component. | /** 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(); | OpenGLContext* getCurrentContext() const throw(); | ||||
| @@ -231,6 +255,10 @@ public: | |||||
| If this returns false, then the context isn't active, so you should avoid | If this returns false, then the context isn't active, so you should avoid | ||||
| making any calls. | 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 | @see OpenGLContext::makeActive | ||||
| */ | */ | ||||
| bool makeCurrentContextActive(); | bool makeCurrentContextActive(); | ||||
| @@ -289,7 +317,6 @@ private: | |||||
| OpenGLPixelFormat preferredPixelFormat; | OpenGLPixelFormat preferredPixelFormat; | ||||
| bool needToUpdateViewport; | bool needToUpdateViewport; | ||||
| void createContext(); | |||||
| void deleteContext(); | void deleteContext(); | ||||
| void updateContextPosition(); | void updateContextPosition(); | ||||
| void internalRepaint (int x, int y, int w, int h); | void internalRepaint (int x, int y, int w, int h); | ||||