diff --git a/dotnet/extlibs/csfml-audio.dll b/dotnet/extlibs/csfml-audio.dll index a13fc46dd..15fbcc8d4 100644 Binary files a/dotnet/extlibs/csfml-audio.dll and b/dotnet/extlibs/csfml-audio.dll differ diff --git a/dotnet/extlibs/csfml-graphics.dll b/dotnet/extlibs/csfml-graphics.dll index 04d258249..850d38014 100644 Binary files a/dotnet/extlibs/csfml-graphics.dll and b/dotnet/extlibs/csfml-graphics.dll differ diff --git a/dotnet/extlibs/csfml-window.dll b/dotnet/extlibs/csfml-window.dll index 0c266f23d..eb2ca713e 100644 Binary files a/dotnet/extlibs/csfml-window.dll and b/dotnet/extlibs/csfml-window.dll differ diff --git a/dotnet/samples/opengl/OpenGL.cs b/dotnet/samples/opengl/OpenGL.cs index 449de17c4..8e27fc0be 100644 --- a/dotnet/samples/opengl/OpenGL.cs +++ b/dotnet/samples/opengl/OpenGL.cs @@ -16,9 +16,6 @@ namespace sample_opengl // Create main window RenderWindow window = new RenderWindow(new VideoMode(800, 600), "SFML.Net OpenGL"); - // Activate it as the target for OpenGL calls - window.SetActive(); - // Setup event handlers window.Closed += new EventHandler(OnClosed); window.KeyPressed += new EventHandler(OnKeyPressed); @@ -79,7 +76,9 @@ namespace sample_opengl // will be rendered on top of the background sprite window.Flush(); - // Activate the window for OpenGL calls + // Activate the window before using OpenGL commands. + // This is useless here because we have only one window which is + // always the active one, but don't forget it if you use multiple windows window.SetActive(); // Clear depth buffer @@ -169,8 +168,6 @@ namespace sample_opengl /// static void OnResized(object sender, SizeEventArgs e) { - RenderWindow window = (RenderWindow)sender; - window.SetActive(); Gl.glViewport(0, 0, (int)e.Width, (int)e.Height); } } diff --git a/dotnet/samples/window/Window.cs b/dotnet/samples/window/Window.cs index e894824bc..56121bb13 100644 --- a/dotnet/samples/window/Window.cs +++ b/dotnet/samples/window/Window.cs @@ -15,9 +15,6 @@ namespace sample_window // Create the main window Window window = new Window(new VideoMode(640, 480, 32), "SFML.Net Window"); - // Activate it as the target for OpenGL calls - window.SetActive(); - // Setup event handlers window.Closed += new EventHandler(OnClosed); window.KeyPressed += new EventHandler(OnKeyPressed); @@ -44,7 +41,9 @@ namespace sample_window // Process events window.DispatchEvents(); - // Set the active window before using OpenGL commands + // Activate the window before using OpenGL commands. + // This is useless here because we have only one window which is + // always the active one, but don't forget it if you use multiple windows window.SetActive(); // Clear color and depth buffer @@ -129,8 +128,6 @@ namespace sample_window /// static void OnResized(object sender, SizeEventArgs e) { - Window window = (Window)sender; - window.SetActive(); Gl.glViewport(0, 0, (int)e.Width, (int)e.Height); } } diff --git a/include/SFML/Window/Context.hpp b/include/SFML/Window/Context.hpp index c00527f4c..b191cba4e 100644 --- a/include/SFML/Window/Context.hpp +++ b/include/SFML/Window/Context.hpp @@ -71,6 +71,18 @@ public : //////////////////////////////////////////////////////////// void SetActive(bool active); + //////////////////////////////////////////////////////////// + /// \brief Make the current thread's reference context active + /// + /// This function is meant to be called internally; it is used + /// to deactivate the current context by activating another one + /// (so that we still have an active context on the current thread). + /// + /// \return True if operation was successful, false otherwise + /// + //////////////////////////////////////////////////////////// + static bool SetReferenceActive(); + private : //////////////////////////////////////////////////////////// diff --git a/samples/window/Window.cpp b/samples/window/Window.cpp index 4d0db932f..92c5f605f 100644 --- a/samples/window/Window.cpp +++ b/samples/window/Window.cpp @@ -17,9 +17,6 @@ int main() // Create the main window sf::Window window(sf::VideoMode(640, 480, 32), "SFML Window"); - // Activate it as the target for OpenGL calls - window.SetActive(); - // Create a clock for measuring the time elapsed sf::Clock clock; @@ -56,7 +53,9 @@ int main() glViewport(0, 0, event.Size.Width, event.Size.Height); } - // Activate the window + // Activate the window before using OpenGL commands. + // This is useless here because we have only one window which is + // always the active one, but don't forget it if you use multiple windows window.SetActive(); // Clear color and depth buffer diff --git a/src/SFML/Audio/AudioDevice.cpp b/src/SFML/Audio/AudioDevice.cpp index 1b96c0979..d9b3ee447 100644 --- a/src/SFML/Audio/AudioDevice.cpp +++ b/src/SFML/Audio/AudioDevice.cpp @@ -45,8 +45,6 @@ namespace sf namespace priv { //////////////////////////////////////////////////////////// -/// Default constructor -//////////////////////////////////////////////////////////// AudioDevice::AudioDevice() { // Create the device @@ -78,8 +76,6 @@ AudioDevice::AudioDevice() } -//////////////////////////////////////////////////////////// -/// Destructor //////////////////////////////////////////////////////////// AudioDevice::~AudioDevice() { @@ -94,8 +90,6 @@ AudioDevice::~AudioDevice() } -//////////////////////////////////////////////////////////// -/// Get the unique instance of the class //////////////////////////////////////////////////////////// AudioDevice& AudioDevice::GetInstance() { @@ -103,8 +97,6 @@ AudioDevice& AudioDevice::GetInstance() } -//////////////////////////////////////////////////////////// -/// Get the OpenAL audio device //////////////////////////////////////////////////////////// ALCdevice* AudioDevice::GetDevice() const { @@ -112,8 +104,6 @@ ALCdevice* AudioDevice::GetDevice() const } -//////////////////////////////////////////////////////////// -/// Get the OpenAL format that matches the given number of channels //////////////////////////////////////////////////////////// ALenum AudioDevice::GetFormatFromChannelsCount(unsigned int channelsCount) const { diff --git a/src/SFML/Audio/AudioDevice.hpp b/src/SFML/Audio/AudioDevice.hpp index d5fc7651c..38d5a4292 100644 --- a/src/SFML/Audio/AudioDevice.hpp +++ b/src/SFML/Audio/AudioDevice.hpp @@ -37,30 +37,30 @@ namespace sf { namespace priv { - //////////////////////////////////////////////////////////// -/// AudioDevice is the high-level wrapper around the audio API, -/// it manages creation and destruction of the audio device and context -/// and stores the device capabilities +/// \brief High-level wrapper around the audio API, it manages +/// the creation and destruction of the audio device and +/// context and stores the device capabilities +/// //////////////////////////////////////////////////////////// class AudioDevice { public : //////////////////////////////////////////////////////////// - /// Default constructor + /// \brief Default constructor /// //////////////////////////////////////////////////////////// AudioDevice(); //////////////////////////////////////////////////////////// - /// Destructor + /// \brief Destructor /// //////////////////////////////////////////////////////////// ~AudioDevice(); //////////////////////////////////////////////////////////// - /// Get the unique instance of the class + /// \brief Get the unique instance of the class /// /// \return Unique instance of the class /// @@ -68,7 +68,7 @@ public : static AudioDevice& GetInstance(); //////////////////////////////////////////////////////////// - /// Get the OpenAL audio device + /// \brief Get the OpenAL audio device /// /// \return OpenAL device (cannot be NULL) /// @@ -76,9 +76,9 @@ public : ALCdevice* GetDevice() const; //////////////////////////////////////////////////////////// - /// Get the OpenAL format that matches the given number of channels + /// \brief Get the OpenAL format that matches the given number of channels /// - /// \param channelsCount : Number of channels + /// \param channelsCount Number of channels /// /// \return Corresponding format /// diff --git a/src/SFML/Graphics/Image.cpp b/src/SFML/Graphics/Image.cpp index 7920b32b2..1a067b141 100644 --- a/src/SFML/Graphics/Image.cpp +++ b/src/SFML/Graphics/Image.cpp @@ -407,8 +407,6 @@ bool Image::CopyScreen(RenderWindow& window, const IntRect& sourceRect) myNeedArrayUpdate = true; myPixelsFlipped = true; - window.SetActive(false); - return true; } else diff --git a/src/SFML/Graphics/Linux/RenderImageImplPBuffer.cpp b/src/SFML/Graphics/Linux/RenderImageImplPBuffer.cpp index 41fdfa57b..19616d4cc 100644 --- a/src/SFML/Graphics/Linux/RenderImageImplPBuffer.cpp +++ b/src/SFML/Graphics/Linux/RenderImageImplPBuffer.cpp @@ -27,7 +27,7 @@ //////////////////////////////////////////////////////////// #include #include -#include +#include #include @@ -58,12 +58,12 @@ RenderImageImplPBuffer::~RenderImageImplPBuffer() if (myPBuffer) glXDestroyGLXPbufferSGIX(myDisplay, myPBuffer); - - XCloseDisplay(myDisplay); + + XCloseDisplay(myDisplay); // This is to make sure that another valid context is made // active after we destroy the P-Buffer's one - Context context; + Context::SetReferenceActive(); } @@ -72,18 +72,18 @@ RenderImageImplPBuffer::~RenderImageImplPBuffer() //////////////////////////////////////////////////////////// bool RenderImageImplPBuffer::IsSupported() { - // Make sure that GLEW is initialized - EnsureGlewInit(); + // Make sure that GLEW is initialized + EnsureGlewInit(); return glxewIsSupported("GLX_SGIX_pbuffer"); } - + //////////////////////////////////////////////////////////// /// /see RenderImageImpl::Create //////////////////////////////////////////////////////////// bool RenderImageImplPBuffer::Create(unsigned int width, unsigned int height, unsigned int, bool depthBuffer) -{ +{ // Store the dimensions myWidth = width; myHeight = height; @@ -91,11 +91,11 @@ bool RenderImageImplPBuffer::Create(unsigned int width, unsigned int height, uns // Define the PBuffer attributes int visualAttributes[] = { - GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT, - GLX_RED_SIZE, 8, - GLX_GREEN_SIZE, 8, - GLX_BLUE_SIZE, 8, + GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, + GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, (depthBuffer ? 24 : 0), 0 @@ -106,24 +106,24 @@ bool RenderImageImplPBuffer::Create(unsigned int width, unsigned int height, uns GLX_PBUFFER_HEIGHT, height, 0 }; - - // Get the available FB configurations - int nbConfigs = 0; - GLXFBConfig* configs = glXChooseFBConfigSGIX(myDisplay, DefaultScreen(myDisplay), visualAttributes, &nbConfigs); - if (!configs || !nbConfigs) - { + + // Get the available FB configurations + int nbConfigs = 0; + GLXFBConfig* configs = glXChooseFBConfigSGIX(myDisplay, DefaultScreen(myDisplay), visualAttributes, &nbConfigs); + if (!configs || !nbConfigs) + { std::cerr << "Impossible to create render image (failed to find a suitable pixel format for PBuffer)" << std::endl; - return false; - } - - // Create the P-Buffer - myPBuffer = glXCreateGLXPbufferSGIX(myDisplay, configs[0], width, height, PBufferAttributes); - if (!myPBuffer) - { - std::cerr << "Impossible to create render image (failed to create the OpenGL PBuffer)" << std::endl; + return false; + } + + // Create the P-Buffer + myPBuffer = glXCreateGLXPbufferSGIX(myDisplay, configs[0], width, height, PBufferAttributes); + if (!myPBuffer) + { + std::cerr << "Impossible to create render image (failed to create the OpenGL PBuffer)" << std::endl; XFree(configs); - return false; - } + return false; + } // Check the actual size of the P-Buffer unsigned int actualWidth, actualHeight; @@ -134,35 +134,35 @@ bool RenderImageImplPBuffer::Create(unsigned int width, unsigned int height, uns std::cerr << "Impossible to create render image (failed to match the requested size). " << "Size: " << actualWidth << "x" << actualHeight << " - " << "Requested: " << width << "x" << height - << std::endl; + << std::endl; XFree(configs); return false; } - // We'll have to share the P-Buffer context with the current context + // We'll have to share the P-Buffer context with the current context GLXDrawable currentDrawable = glXGetCurrentDrawable(); GLXContext currentContext = glXGetCurrentContext(); if (currentContext) - glXMakeCurrent(myDisplay, NULL, NULL); - - // Create the context - XVisualInfo* visual = glXGetVisualFromFBConfig(myDisplay, configs[0]); - myContext = glXCreateContext(myDisplay, visual, currentContext, true); - if (!myContext) - { + glXMakeCurrent(myDisplay, NULL, NULL); + + // Create the context + XVisualInfo* visual = glXGetVisualFromFBConfig(myDisplay, configs[0]); + myContext = glXCreateContext(myDisplay, visual, currentContext, true); + if (!myContext) + { std::cerr << "Impossible to create render image (failed to create the OpenGL context)" << std::endl; - XFree(configs); - XFree(visual); - return false; - } - - // Restore the previous active context + XFree(configs); + XFree(visual); + return false; + } + + // Restore the previous active context if (currentContext) - glXMakeCurrent(myDisplay, currentDrawable, currentContext); - - // Cleanup resources - XFree(configs); - XFree(visual); + glXMakeCurrent(myDisplay, currentDrawable, currentContext); + + // Cleanup resources + XFree(configs); + XFree(visual); return true; } @@ -175,22 +175,25 @@ bool RenderImageImplPBuffer::Activate(bool active) { if (active) { - if (myPBuffer && myContext && (glXGetCurrentContext() != myContext)) + if (myPBuffer && myContext) { - // Bind the OpenGL context of the P-Buffer - if (!glXMakeCurrent(myDisplay, myPBuffer, myContext)) - { - std::cout << "Failed to activate render image" << std::endl; - return false; - } + if (glXGetCurrentContext() != myContext) + return glXMakeCurrent(myDisplay, myPBuffer, myContext) != 0; + else + return true; + } + else + { + return false; } } else { - // We don't actually unbind the P-Buffer, for performances reasons + // To deactivate the P-Buffer's context, we actually activate + // another one so that we make sure that there is always an + // active context for subsequent graphics operations + return Context::SetReferenceActive(); } - - return true; } @@ -199,10 +202,6 @@ bool RenderImageImplPBuffer::Activate(bool active) //////////////////////////////////////////////////////////// bool RenderImageImplPBuffer::UpdateTexture(unsigned int textureId) { - // Store the current active context - GLXDrawable currentDrawable = glXGetCurrentDrawable(); - GLXContext currentContext = glXGetCurrentContext(); - if (Activate(true)) { // Bind the texture @@ -212,8 +211,8 @@ bool RenderImageImplPBuffer::UpdateTexture(unsigned int textureId) // Copy the rendered pixels to the image GLCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, myWidth, myHeight)); - // Restore the previous context - glXMakeCurrent(myDisplay, currentDrawable, currentContext); + // Deactivate the P-Buffer + Activate(false); return true; } diff --git a/src/SFML/Graphics/RenderWindow.cpp b/src/SFML/Graphics/RenderWindow.cpp index 8cfb19dd4..853da395a 100644 --- a/src/SFML/Graphics/RenderWindow.cpp +++ b/src/SFML/Graphics/RenderWindow.cpp @@ -48,6 +48,7 @@ RenderWindow::RenderWindow() //////////////////////////////////////////////////////////// RenderWindow::RenderWindow(VideoMode mode, const std::string& title, unsigned long style, const ContextSettings& settings) { + // Don't call the base class constructor because it contains virtual function calls Create(mode, title, style, settings); } @@ -57,6 +58,7 @@ RenderWindow::RenderWindow(VideoMode mode, const std::string& title, unsigned lo //////////////////////////////////////////////////////////// RenderWindow::RenderWindow(WindowHandle handle, const ContextSettings& settings) { + // Don't call the base class constructor because it contains virtual function calls Create(handle, settings); } diff --git a/src/SFML/Graphics/Win32/RenderImageImplPBuffer.cpp b/src/SFML/Graphics/Win32/RenderImageImplPBuffer.cpp index de54c01d1..d0e8489c3 100644 --- a/src/SFML/Graphics/Win32/RenderImageImplPBuffer.cpp +++ b/src/SFML/Graphics/Win32/RenderImageImplPBuffer.cpp @@ -67,7 +67,7 @@ RenderImageImplPBuffer::~RenderImageImplPBuffer() // This is to make sure that another valid context is made // active after we destroy the P-Buffer's one - Context context; + Context::SetReferenceActive(); } @@ -167,23 +167,25 @@ bool RenderImageImplPBuffer::Activate(bool active) { if (active) { - if (myDeviceContext && myContext && (wglGetCurrentContext() != myContext)) + if (myDeviceContext && myContext) { - // Bind the OpenGL context of the P-Buffer - if (!wglMakeCurrent(myDeviceContext, myContext)) - { - std::cout << "Failed to activate render image" << std::endl; - return false; - } + if (wglGetCurrentContext() != myContext) + return wglMakeCurrent(myDeviceContext, myContext) != 0; + else + return true; + } + else + { + return false; } } else { - // We don't actually unbind the P-Buffer, - // for performances and consistency reasons + // To deactivate the P-Buffer's context, we actually activate + // another one so that we make sure that there is always an + // active context for subsequent graphics operations + return Context::SetReferenceActive(); } - - return true; } @@ -192,10 +194,6 @@ bool RenderImageImplPBuffer::Activate(bool active) //////////////////////////////////////////////////////////// bool RenderImageImplPBuffer::UpdateTexture(unsigned int textureId) { - // Store the current active context - HDC currentDC = wglGetCurrentDC(); - HGLRC currentContext = wglGetCurrentContext(); - if (Activate(true)) { // Bind the texture @@ -205,8 +203,8 @@ bool RenderImageImplPBuffer::UpdateTexture(unsigned int textureId) // Copy the rendered pixels to the image GLCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, myWidth, myHeight)); - // Restore the previous context - wglMakeCurrent(currentDC, currentContext); + // Deactivate the P-Buffer + Activate(false); return true; } diff --git a/src/SFML/Window/Context.cpp b/src/SFML/Window/Context.cpp index 3054d0b54..be53a8d1c 100644 --- a/src/SFML/Window/Context.cpp +++ b/src/SFML/Window/Context.cpp @@ -54,4 +54,11 @@ void Context::SetActive(bool active) } +//////////////////////////////////////////////////////////// +bool Context::SetReferenceActive() +{ + return priv::ContextGL::SetReferenceActive(); +} + + } // namespace sf diff --git a/src/SFML/Window/ContextGL.cpp b/src/SFML/Window/ContextGL.cpp index 8d0be530a..c8a6d09e3 100644 --- a/src/SFML/Window/ContextGL.cpp +++ b/src/SFML/Window/ContextGL.cpp @@ -99,8 +99,9 @@ ContextGL::~ContextGL() { threadContext = NULL; } - else if (threadContext != NULL) + else if (threadContext) { + // Don't call this->SetActive(false), it would lead to a pure virtual function call threadContext->SetActive(true); } } @@ -116,27 +117,41 @@ const ContextSettings& ContextGL::GetSettings() const //////////////////////////////////////////////////////////// bool ContextGL::SetActive(bool active) { - if (MakeCurrent(active)) + if (active) { - if (active && (threadContext == 0)) + // Activate the context + if (MakeCurrent()) { // If this is the first context to be activated on this thread, make // it the reference context for the whole thread - threadContext = this; - } - else if (!active && (threadContext != NULL) && (threadContext != this)) - { - // Activate the reference context for this thread to ensure - // that there is always an active context for subsequent graphics operations - threadContext->SetActive(true); - } + if (!threadContext) + threadContext = this; - return true; + return true; + } } else { - return false; + // Deactivate the context + if (threadContext && (threadContext != this)) + { + // To deactivate the context, we actually activate another one + // so that we make sure that there is always an active context + // for subsequent graphics operations + return threadContext->SetActive(true); + } } + + // If we got there then something failed + return false; +} + + +//////////////////////////////////////////////////////////// +bool ContextGL::SetReferenceActive() +{ + if (threadContext) + return threadContext->SetActive(true); } diff --git a/src/SFML/Window/ContextGL.hpp b/src/SFML/Window/ContextGL.hpp index 97a67d004..d0b6461c1 100644 --- a/src/SFML/Window/ContextGL.hpp +++ b/src/SFML/Window/ContextGL.hpp @@ -129,6 +129,18 @@ public : //////////////////////////////////////////////////////////// virtual void UseVerticalSync(bool enabled) = 0; + //////////////////////////////////////////////////////////// + /// \brief Make the current thread's reference context active + /// + /// This function is meant to be called internally; it is used + /// to deactivate the current context by activating another one + /// (so that we still have an active context on the current thread). + /// + /// \return True if operation was successful, false otherwise + /// + //////////////////////////////////////////////////////////// + static bool SetReferenceActive(); + protected : //////////////////////////////////////////////////////////// @@ -140,15 +152,13 @@ protected : ContextGL(); //////////////////////////////////////////////////////////// - /// \brief Activate or deactivate the context as the current target + /// \brief Activate the context as the current target /// for rendering /// - /// \param active True to activate, false to deactivate - /// /// \return True on success, false if any error happened /// //////////////////////////////////////////////////////////// - virtual bool MakeCurrent(bool active) = 0; + virtual bool MakeCurrent() = 0; //////////////////////////////////////////////////////////// /// \brief Evaluate a pixel format configuration diff --git a/src/SFML/Window/Linux/ContextGLX.cpp b/src/SFML/Window/Linux/ContextGLX.cpp index 1817151a4..92ca7c50e 100644 --- a/src/SFML/Window/Linux/ContextGLX.cpp +++ b/src/SFML/Window/Linux/ContextGLX.cpp @@ -113,28 +113,18 @@ ContextGLX::~ContextGLX() //////////////////////////////////////////////////////////// -bool ContextGLX::MakeCurrent(bool active) +bool ContextGLX::MakeCurrent() { - if (active) + if (myContext) { - if (myContext) - { - if (glXGetCurrentContext() != myContext) - return glXMakeCurrent(myDisplay, myWindow, myContext) != 0; - else - return true; - } + if (glXGetCurrentContext() != myContext) + return glXMakeCurrent(myDisplay, myWindow, myContext) != 0; else - { - return false; - } + return true; } else { - if (glXGetCurrentContext() == myContext) - return glXMakeCurrent(myDisplay, None, NULL) != 0; - else - return true; + return false; } } diff --git a/src/SFML/Window/Linux/ContextGLX.hpp b/src/SFML/Window/Linux/ContextGLX.hpp index c1ea13d7d..933ff5c64 100644 --- a/src/SFML/Window/Linux/ContextGLX.hpp +++ b/src/SFML/Window/Linux/ContextGLX.hpp @@ -71,15 +71,13 @@ public : ~ContextGLX(); //////////////////////////////////////////////////////////// - /// \brief Activate or deactivate the context as the current target + /// \brief Activate the context as the current target /// for rendering /// - /// \param active True to activate, false to deactivate - /// /// \return True on success, false if any error happened /// //////////////////////////////////////////////////////////// - virtual bool MakeCurrent(bool active); + virtual bool MakeCurrent(); //////////////////////////////////////////////////////////// /// \brief Display what has been rendered to the context so far diff --git a/src/SFML/Window/Win32/ContextWGL.cpp b/src/SFML/Window/Win32/ContextWGL.cpp index 3a52454f0..46a1b5eb2 100644 --- a/src/SFML/Window/Win32/ContextWGL.cpp +++ b/src/SFML/Window/Win32/ContextWGL.cpp @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include @@ -38,20 +40,20 @@ namespace priv { //////////////////////////////////////////////////////////// ContextWGL::ContextWGL(ContextWGL* shared) : -myWindow (NULL), -myDC (NULL), -myContext (NULL), -myOwnsWindow(true) +myWindow (NULL), +myDeviceContext(NULL), +myContext (NULL), +myOwnsWindow (true) { // TODO : try to create a bitmap in memory instead of a dummy window // Create a dummy window (disabled and hidden) myWindow = CreateWindowA("STATIC", "", WS_POPUP | WS_DISABLED, 0, 0, 1, 1, NULL, NULL, GetModuleHandle(NULL), NULL); ShowWindow(myWindow, SW_HIDE); - myDC = GetDC(myWindow); + myDeviceContext = GetDC(myWindow); // Create the context - if (myDC) + if (myDeviceContext) CreateContext(shared, VideoMode::GetDesktopMode().BitsPerPixel, ContextSettings(0, 0, 0)); // Activate the context @@ -61,17 +63,17 @@ myOwnsWindow(true) //////////////////////////////////////////////////////////// ContextWGL::ContextWGL(ContextWGL* shared, const WindowImpl* owner, unsigned int bitsPerPixel, const ContextSettings& settings) : -myWindow (NULL), -myDC (NULL), -myContext (NULL), -myOwnsWindow(false) +myWindow (NULL), +myDeviceContext(NULL), +myContext (NULL), +myOwnsWindow (false) { // Get the owner window and its device context myWindow = static_cast(owner->GetHandle()); - myDC = GetDC(myWindow); + myDeviceContext = GetDC(myWindow); // Create the context - if (myDC) + if (myDeviceContext) CreateContext(shared, bitsPerPixel, settings); // Activate the context @@ -91,8 +93,8 @@ ContextWGL::~ContextWGL() } // Release the DC - if (myWindow && myDC) - ReleaseDC(myWindow, myDC); + if (myWindow && myDeviceContext) + ReleaseDC(myWindow, myDeviceContext); // Destroy the window if we own it if (myWindow && myOwnsWindow) @@ -101,28 +103,18 @@ ContextWGL::~ContextWGL() //////////////////////////////////////////////////////////// -bool ContextWGL::MakeCurrent(bool active) +bool ContextWGL::MakeCurrent() { - if (active) + if (myDeviceContext && myContext) { - if (myDC && myContext) - { - if (wglGetCurrentContext() != myContext) - return wglMakeCurrent(myDC, myContext) != 0; - else - return true; - } + if (wglGetCurrentContext() != myContext) + return wglMakeCurrent(myDeviceContext, myContext) != 0; else - { - return false; - } + return true; } else { - if (wglGetCurrentContext() == myContext) - return wglMakeCurrent(NULL, NULL) != 0; - else - return true; + return false; } } @@ -130,8 +122,8 @@ bool ContextWGL::MakeCurrent(bool active) //////////////////////////////////////////////////////////// void ContextWGL::Display() { - if (myDC && myContext) - SwapBuffers(myDC); + if (myDeviceContext && myContext) + SwapBuffers(myDeviceContext); } @@ -180,7 +172,7 @@ void ContextWGL::CreateContext(ContextWGL* shared, unsigned int bitsPerPixel, co int formats[128]; UINT nbFormats; float floatAttributes[] = {0, 0}; - bool isValid = wglChoosePixelFormatARB(myDC, intAttributes, floatAttributes, sizeof(formats) / sizeof(*formats), formats, &nbFormats) != 0; + bool isValid = wglChoosePixelFormatARB(myDeviceContext, intAttributes, floatAttributes, sizeof(formats) / sizeof(*formats), formats, &nbFormats) != 0; if (!isValid || (nbFormats == 0)) { if (mySettings.AntialiasingLevel > 2) @@ -190,7 +182,7 @@ void ContextWGL::CreateContext(ContextWGL* shared, unsigned int bitsPerPixel, co << mySettings.AntialiasingLevel << " antialiasing levels ; trying with 2 levels" << std::endl; mySettings.AntialiasingLevel = intAttributes[1] = 2; - isValid = wglChoosePixelFormatARB(myDC, intAttributes, floatAttributes, sizeof(formats) / sizeof(*formats), formats, &nbFormats) != 0; + isValid = wglChoosePixelFormatARB(myDeviceContext, intAttributes, floatAttributes, sizeof(formats) / sizeof(*formats), formats, &nbFormats) != 0; } if (!isValid || (nbFormats == 0)) @@ -211,7 +203,7 @@ void ContextWGL::CreateContext(ContextWGL* shared, unsigned int bitsPerPixel, co PIXELFORMATDESCRIPTOR attributes; attributes.nSize = sizeof(attributes); attributes.nVersion = 1; - DescribePixelFormat(myDC, formats[i], sizeof(attributes), &attributes); + DescribePixelFormat(myDeviceContext, formats[i], sizeof(attributes), &attributes); // Evaluate the current configuration int color = attributes.cRedBits + attributes.cGreenBits + attributes.cBlueBits + attributes.cAlphaBits; @@ -243,7 +235,7 @@ void ContextWGL::CreateContext(ContextWGL* shared, unsigned int bitsPerPixel, co descriptor.cStencilBits = static_cast(mySettings.StencilBits); // Get the pixel format that best matches our requirements - bestFormat = ChoosePixelFormat(myDC, &descriptor); + bestFormat = ChoosePixelFormat(myDeviceContext, &descriptor); if (bestFormat == 0) { std::cerr << "Failed to find a suitable pixel format for device context -- cannot create OpenGL context" << std::endl; @@ -255,12 +247,12 @@ void ContextWGL::CreateContext(ContextWGL* shared, unsigned int bitsPerPixel, co PIXELFORMATDESCRIPTOR actualFormat; actualFormat.nSize = sizeof(actualFormat); actualFormat.nVersion = 1; - DescribePixelFormat(myDC, bestFormat, sizeof(actualFormat), &actualFormat); + DescribePixelFormat(myDeviceContext, bestFormat, sizeof(actualFormat), &actualFormat); mySettings.DepthBits = actualFormat.cDepthBits; mySettings.StencilBits = actualFormat.cStencilBits; // Set the chosen pixel format - if (!SetPixelFormat(myDC, bestFormat, &actualFormat)) + if (!SetPixelFormat(myDeviceContext, bestFormat, &actualFormat)) { std::cerr << "Failed to set pixel format for device context -- cannot create OpenGL context" << std::endl; return; @@ -279,13 +271,13 @@ void ContextWGL::CreateContext(ContextWGL* shared, unsigned int bitsPerPixel, co WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0, 0 }; - myContext = wglCreateContextAttribsARB(myDC, sharedContext, attributes); + myContext = wglCreateContextAttribsARB(myDeviceContext, sharedContext, attributes); } // If the OpenGL 3.0 context failed, create a regular OpenGL 1.x context if (!myContext) { - myContext = wglCreateContext(myDC); + myContext = wglCreateContext(myDeviceContext); if (!myContext) { std::cerr << "Failed to create an OpenGL context for this window" << std::endl; @@ -295,6 +287,10 @@ void ContextWGL::CreateContext(ContextWGL* shared, unsigned int bitsPerPixel, co // Share this context with others if (sharedContext) { + // wglShareLists doesn't seem to be thread-safe + static Mutex mutex; + Lock lock(mutex); + if (!wglShareLists(sharedContext, myContext)) std::cerr << "Failed to share the OpenGL context" << std::endl; } diff --git a/src/SFML/Window/Win32/ContextWGL.hpp b/src/SFML/Window/Win32/ContextWGL.hpp index 2ab61ce05..379b6fe23 100644 --- a/src/SFML/Window/Win32/ContextWGL.hpp +++ b/src/SFML/Window/Win32/ContextWGL.hpp @@ -70,15 +70,13 @@ public : ~ContextWGL(); //////////////////////////////////////////////////////////// - /// \brief Activate or deactivate the context as the current target + /// \brief Activate the context as the current target /// for rendering /// - /// \param active True to activate, false to deactivate - /// /// \return True on success, false if any error happened /// //////////////////////////////////////////////////////////// - virtual bool MakeCurrent(bool active); + virtual bool MakeCurrent(); //////////////////////////////////////////////////////////// /// \brief Display what has been rendered to the context so far @@ -122,10 +120,10 @@ private : //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - HWND myWindow; ///< Window to which the context is attached - HDC myDC; ///< Device context of the window - HGLRC myContext; ///< OpenGL context - bool myOwnsWindow; ///< Did we create the host window? + HWND myWindow; ///< Window to which the context is attached + HDC myDeviceContext; ///< Device context of the window + HGLRC myContext; ///< OpenGL context + bool myOwnsWindow; ///< Did we create the host window? }; } // namespace priv diff --git a/src/SFML/Window/Window.cpp b/src/SFML/Window/Window.cpp index 89567b990..7b734351c 100644 --- a/src/SFML/Window/Window.cpp +++ b/src/SFML/Window/Window.cpp @@ -27,7 +27,6 @@ //////////////////////////////////////////////////////////// #include #include -#include #include #include #include @@ -127,16 +126,9 @@ void Window::Create(VideoMode mode, const std::string& title, unsigned long styl style |= Style::Titlebar; // Recreate the window implementation - delete myWindow; myWindow = priv::WindowImpl::New(mode, title, style); - // Make sure another context is bound, so that: - // - the context creation can request OpenGL extensions if necessary - // - myContext can safely be destroyed (it's no longer bound) - Context context; - // Recreate the context - delete myContext; myContext = priv::ContextGL::New(myWindow, mode.BitsPerPixel, settings); // Perform common initializations @@ -147,17 +139,13 @@ void Window::Create(VideoMode mode, const std::string& title, unsigned long styl //////////////////////////////////////////////////////////// void Window::Create(WindowHandle handle, const ContextSettings& settings) { - // Recreate the window implementation + // Destroy the previous window implementation Close(); + + // Recreate the window implementation myWindow = priv::WindowImpl::New(handle); - // Make sure another context is bound, so that: - // - the context creation can request OpenGL extensions if necessary - // - myContext can safely be destroyed (it's no longer bound) - Context context; - // Recreate the context - delete myContext; myContext = priv::ContextGL::New(myWindow, VideoMode::GetDesktopMode().BitsPerPixel, settings); // Perform common initializations @@ -325,6 +313,7 @@ bool Window::SetActive(bool active) const } else { + std::cerr << "Trying to activate the window, but it doesn't have a valid context" << std::endl; return false; } } @@ -349,11 +338,8 @@ void Window::Display() myClock.Reset(); // Display the backbuffer on screen - if (SetActive(true)) - { + if (SetActive()) myContext->Display(); - SetActive(false); - } } @@ -435,7 +421,7 @@ void Window::Initialize() myLastFrameTime = 0.f; // Activate the window - SetActive(true); + SetActive(); // Notify the derived class OnCreate();