diff --git a/include/SFML/Graphics/RenderImage.hpp b/include/SFML/Graphics/RenderImage.hpp index aa65cd09..ef6703b9 100644 --- a/include/SFML/Graphics/RenderImage.hpp +++ b/include/SFML/Graphics/RenderImage.hpp @@ -177,20 +177,6 @@ public : //////////////////////////////////////////////////////////// const Image& GetImage() const; - //////////////////////////////////////////////////////////// - /// \brief Check whether the system supports render images or not - /// - /// It is very important to always call this function before - /// trying to use the RenderImage class, as the feature may not - /// be supported on all platforms (especially very old ones). - /// If this function returns false, then you won't be able - /// to use the class at all. - /// - /// \return True if the RenderImage class can be used - /// - //////////////////////////////////////////////////////////// - static bool IsAvailable(); - private : //////////////////////////////////////////////////////////// diff --git a/include/SFML/Window/Context.hpp b/include/SFML/Window/Context.hpp index 0e65732c..def5acf9 100644 --- a/include/SFML/Window/Context.hpp +++ b/include/SFML/Window/Context.hpp @@ -30,6 +30,7 @@ //////////////////////////////////////////////////////////// #include #include +#include #include @@ -69,8 +70,25 @@ public : /// /// \param active True to activate, false to deactivate /// + /// \return True on success, false on failure + /// //////////////////////////////////////////////////////////// - void SetActive(bool active); + bool SetActive(bool active); + +public : + + //////////////////////////////////////////////////////////// + /// \brief Construct a in-memory context + /// + /// This constructor is for internal use, you don't need + /// to bother with it. + /// + /// \param settings Creation parameters + /// \param width Back buffer width + /// \param height Back buffer height + /// + //////////////////////////////////////////////////////////// + Context(const ContextSettings& settings, unsigned int width, unsigned int height); private : diff --git a/include/SFML/Window/ContextSettings.hpp b/include/SFML/Window/ContextSettings.hpp index b920ba45..946654ec 100644 --- a/include/SFML/Window/ContextSettings.hpp +++ b/include/SFML/Window/ContextSettings.hpp @@ -45,7 +45,7 @@ struct ContextSettings /// \param minor Minor number of the context version /// //////////////////////////////////////////////////////////// - explicit ContextSettings(unsigned int depth = 24, unsigned int stencil = 8, unsigned int antialiasing = 0, unsigned int major = 2, unsigned int minor = 0) : + explicit ContextSettings(unsigned int depth = 0, unsigned int stencil = 0, unsigned int antialiasing = 0, unsigned int major = 2, unsigned int minor = 0) : DepthBits (depth), StencilBits (stencil), AntialiasingLevel(antialiasing), diff --git a/src/SFML/Graphics/CMakeLists.txt b/src/SFML/Graphics/CMakeLists.txt index f8a6c538..e2855ac3 100644 --- a/src/SFML/Graphics/CMakeLists.txt +++ b/src/SFML/Graphics/CMakeLists.txt @@ -31,7 +31,8 @@ set(SRC ${SRCROOT}/RenderImageImpl.hpp ${SRCROOT}/RenderImageImplFBO.cpp ${SRCROOT}/RenderImageImplFBO.hpp - ${SRCROOT}/RenderImageImplPBuffer.hpp + ${SRCROOT}/RenderImageImplDefault.cpp + ${SRCROOT}/RenderImageImplDefault.hpp ${SRCROOT}/RenderTarget.cpp ${INCROOT}/RenderTarget.hpp ${SRCROOT}/RenderWindow.cpp @@ -50,27 +51,6 @@ set(SRC ${SRCROOT}/stb_image/stb_image_write.h ) -# add platform specific sources -if(WINDOWS) - set(SRC - ${SRC} - ${SRCROOT}/Win32/RenderImageImplPBuffer.cpp - ${SRCROOT}/Win32/RenderImageImplPBuffer.hpp - ) -elseif(LINUX) - set(SRC - ${SRC} - ${SRCROOT}/Linux/RenderImageImplPBuffer.cpp - ${SRCROOT}/Linux/RenderImageImplPBuffer.hpp - ) -elseif(MACOSX) - set(SRC - ${SRC} - ${SRCROOT}/OSX/RenderImageImplPBuffer.cpp - ${SRCROOT}/OSX/RenderImageImplPBuffer.hpp - ) -endif() - # let CMake know about our additional graphics libraries paths (on Windows and OSX) if (WINDOWS OR MACOSX) set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/extlibs/headers/freetype") diff --git a/src/SFML/Graphics/Linux/RenderImageImplPBuffer.cpp b/src/SFML/Graphics/Linux/RenderImageImplPBuffer.cpp deleted file mode 100644 index 279a8037..00000000 --- a/src/SFML/Graphics/Linux/RenderImageImplPBuffer.cpp +++ /dev/null @@ -1,207 +0,0 @@ -//////////////////////////////////////////////////////////// -// -// SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) -// -// This software is provided 'as-is', without any express or implied warranty. -// In no event will the authors be held liable for any damages arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it freely, -// subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; -// you must not claim that you wrote the original software. -// If you use this software in a product, an acknowledgment -// in the product documentation would be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, -// and must not be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source distribution. -// -//////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////// -// Headers -//////////////////////////////////////////////////////////// -#include -#include -#include -#include - - -namespace sf -{ -namespace priv -{ -//////////////////////////////////////////////////////////// -RenderImageImplPBuffer::RenderImageImplPBuffer() : -myPBuffer(0), -myContext(NULL), -myWidth (0), -myHeight (0) -{ - myDisplay = XOpenDisplay(NULL); -} - - -//////////////////////////////////////////////////////////// -RenderImageImplPBuffer::~RenderImageImplPBuffer() -{ - EnsureGlContext(); - - if (myContext) - glXDestroyContext(myDisplay, myContext); - - if (myPBuffer) - glXDestroyGLXPbufferSGIX(myDisplay, myPBuffer); - - XCloseDisplay(myDisplay); -} - - -//////////////////////////////////////////////////////////// -bool RenderImageImplPBuffer::IsSupported() -{ - EnsureGlContext(); - - // Make sure that GLEW is initialized - EnsureGlewInit(); - - return GLXEW_SGIX_pbuffer && GLXEW_SGIX_fbconfig; -} - - -//////////////////////////////////////////////////////////// -bool RenderImageImplPBuffer::Create(unsigned int width, unsigned int height, unsigned int, bool depthBuffer) -{ - // Store the dimensions - myWidth = width; - myHeight = height; - - // Define the PBuffer attributes - int visualAttributes[] = - { - 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_ALPHA_SIZE, 8, - GLX_DEPTH_SIZE, (depthBuffer ? 24 : 0), - 0 - }; - int PBufferAttributes[] = - { - GLX_PBUFFER_WIDTH, width, - GLX_PBUFFER_HEIGHT, height, - 0 - }; - - // Get the available FB configurations - int nbConfigs = 0; - GLXFBConfig* configs = glXChooseFBConfigSGIX(myDisplay, DefaultScreen(myDisplay), visualAttributes, &nbConfigs); - if (!configs || !nbConfigs) - { - Err() << "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) - { - Err() << "Impossible to create render image (failed to create the OpenGL PBuffer)" << std::endl; - XFree(configs); - return false; - } - - // Check the actual size of the P-Buffer - unsigned int actualWidth, actualHeight; - glXQueryGLXPbufferSGIX(myDisplay, myPBuffer, GLX_WIDTH_SGIX, &actualWidth); - glXQueryGLXPbufferSGIX(myDisplay, myPBuffer, GLX_HEIGHT_SGIX, &actualHeight); - if ((actualWidth != width) || (actualHeight != height)) - { - Err() << "Impossible to create render image (failed to match the requested size). " - << "Size: " << actualWidth << "x" << actualHeight << " - " - << "Requested: " << width << "x" << height - << std::endl; - XFree(configs); - return false; - } - - // We'll have to share the P-Buffer context with the current context - GLXDrawable currentDrawable = glXGetCurrentDrawable(); - GLXContext currentContext = glXGetCurrentContext(); - if (currentContext) - glXMakeCurrent(myDisplay, 0, NULL); - - // Create the context - XVisualInfo* visual = glXGetVisualFromFBConfig(myDisplay, configs[0]); - myContext = glXCreateContext(myDisplay, visual, currentContext, true); - if (!myContext) - { - Err() << "Impossible to create render image (failed to create the OpenGL context)" << std::endl; - XFree(configs); - XFree(visual); - return false; - } - - // Restore the previous active context - if (currentContext) - glXMakeCurrent(myDisplay, currentDrawable, currentContext); - - // Cleanup resources - XFree(configs); - XFree(visual); - - return true; -} - - -//////////////////////////////////////////////////////////// -bool RenderImageImplPBuffer::Activate(bool active) -{ - if (active) - { - if (myPBuffer && myContext) - { - if (glXGetCurrentContext() != myContext) - return glXMakeCurrent(myDisplay, myPBuffer, myContext) != 0; - else - return true; - } - else - { - return false; - } - } - else - { - // 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 - // @odo fixme - //return Context::SetReferenceActive(); - return true; - } -} - - -//////////////////////////////////////////////////////////// -void RenderImageImplPBuffer::UpdateTexture(unsigned int textureId) -{ - GLint previous; - GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous)); - - // Copy the rendered pixels to the image - GLCheck(glBindTexture(GL_TEXTURE_2D, textureId)); - GLCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, myWidth, myHeight)); - - GLCheck(glBindTexture(GL_TEXTURE_2D, previous)); -} - -} // namespace priv - -} // namespace sf diff --git a/src/SFML/Graphics/OSX/RenderImageImplPBuffer.cpp b/src/SFML/Graphics/OSX/RenderImageImplPBuffer.cpp deleted file mode 100644 index 3e8ab417..00000000 --- a/src/SFML/Graphics/OSX/RenderImageImplPBuffer.cpp +++ /dev/null @@ -1,202 +0,0 @@ -//////////////////////////////////////////////////////////// -// -// SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), -// Laurent Gomila (laurent.gom@gmail.com), -// -// This software is provided 'as-is', without any express or implied warranty. -// In no event will the authors be held liable for any damages arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it freely, -// subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; -// you must not claim that you wrote the original software. -// If you use this software in a product, an acknowledgment -// in the product documentation would be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, -// and must not be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source distribution. -// -//////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////// -// Headers -//////////////////////////////////////////////////////////// -#include -#include -#include -#include - -namespace sf -{ -namespace priv -{ -//////////////////////////////////////////////////////////// -RenderImageImplPBuffer::RenderImageImplPBuffer() : - myPBuffer(NULL), - myContext(NULL), - myWidth (0), - myHeight (0) -{ - /* Nothing else */ -} - - -//////////////////////////////////////////////////////////// -RenderImageImplPBuffer::~RenderImageImplPBuffer() -{ - if (myPBuffer && aglDestroyPBuffer(myPBuffer) == GL_FALSE) { - sf::Err() - << "An error occurs while destroying the PBuffer in " - << __PRETTY_FUNCTION__ - << ". The error code is " - << aglGetError() - << std::endl; - } - - if (myContext && aglDestroyContext(myContext) == GL_FALSE) { - sf::Err() - << "An error occurs while destroying the context in " - << __PRETTY_FUNCTION__ - << ". The error code is " - << aglGetError() - << std::endl; - } -} - - -//////////////////////////////////////////////////////////// -bool RenderImageImplPBuffer::IsSupported() -{ - EnsureGlContext(); - - const GLubyte* strExt = glGetString(GL_EXTENSIONS); - GLboolean isSupported = gluCheckExtension((const GLubyte*)"GL_APPLE_pixel_buffer", strExt); - - return isSupported; -} - - -//////////////////////////////////////////////////////////// -bool RenderImageImplPBuffer::Create(unsigned int width, unsigned int height, unsigned int, bool depthBuffer) -{ - // Store the dimensions - myWidth = width; - myHeight = height; - - // Create the pixel format. - GLint attribs[] = { - AGL_RGBA, - AGL_RED_SIZE, 8, - AGL_GREEN_SIZE, 8, - AGL_BLUE_SIZE, 8, - AGL_ALPHA_SIZE, 8, - AGL_DEPTH_SIZE, (depthBuffer ? 24 : 0), - 0 - }; - - AGLPixelFormat pf = aglChoosePixelFormat(NULL, 0, attribs); - if (!pf) { - sf::Err() - << "Couldn't create the pixel format for the PBuffer." - << std::endl; - - return false; - } - - // Create the context. - myContext = aglCreateContext(pf, NULL); - if (!myContext) { - sf::Err() - << "Couldn't create the context for the PBuffer. (Error : " - << aglGetError() - << ")" - << std::endl; - - return false; - } - - // Create the PBuffer. - GLboolean status = aglCreatePBuffer(myWidth, myHeight, GL_TEXTURE_RECTANGLE_EXT, GL_RGBA, 0, &myPBuffer); - if (status == GL_FALSE) { - sf::Err() - << "Couldn't create the PBuffer. (Error : " - << aglGetError() - << ")" - << std::endl; - - return false; - } - - // Set up the PBuffer with the context. - GLint screen = aglGetVirtualScreen(myContext); - if (screen == -1) { - sf::Err() - << "Couldn't get the virtual screen of the context used with the PBuffer. (Error : " - << aglGetError() - << ")" - << std::endl; - - return false; - } - - status = aglSetPBuffer(myContext, myPBuffer, 0, 0, screen); - if (status == GL_FALSE) { - sf::Err() - << "Couldn't set up the PBuffer with the context. (Error : " - << aglGetError() - << ")" - << std::endl; - - return false; - } - - return true; -} - - -//////////////////////////////////////////////////////////// -bool RenderImageImplPBuffer::Activate(bool active) -{ - if (active) - { - if (!myContext || !myPBuffer) // Not created yet. - return false; - - if (aglGetCurrentContext() == myContext) - return true; - else - return aglSetCurrentContext(myContext); - } - else - { - // 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 - // @todo fixme - // return Context::SetReferenceActive(); - return true; - } -} - - -//////////////////////////////////////////////////////////// -void RenderImageImplPBuffer::UpdateTexture(unsigned int textureId) -{ - GLint previous; - GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous)); - - // Copy the rendered pixels to the image - GLCheck(glBindTexture(GL_TEXTURE_2D, textureId)); - GLCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, myWidth, myHeight)); - - GLCheck(glBindTexture(GL_TEXTURE_2D, previous)); -} - -} // namespace priv - -} // namespace sf diff --git a/src/SFML/Graphics/OSX/RenderImageImplPBuffer.hpp b/src/SFML/Graphics/OSX/RenderImageImplPBuffer.hpp deleted file mode 100644 index 192eb9a1..00000000 --- a/src/SFML/Graphics/OSX/RenderImageImplPBuffer.hpp +++ /dev/null @@ -1,116 +0,0 @@ -//////////////////////////////////////////////////////////// -// -// SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), -// Laurent Gomila (laurent.gom@gmail.com), -// -// This software is provided 'as-is', without any express or implied warranty. -// In no event will the authors be held liable for any damages arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it freely, -// subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; -// you must not claim that you wrote the original software. -// If you use this software in a product, an acknowledgment -// in the product documentation would be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, -// and must not be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source distribution. -// -//////////////////////////////////////////////////////////// - -#ifndef SFML_RENDERIMAGEIMPLPBUFFER_HPP -#define SFML_RENDERIMAGEIMPLPBUFFER_HPP - -//////////////////////////////////////////////////////////// -// Headers -//////////////////////////////////////////////////////////// -#include -#include -#include -#include - -namespace sf -{ -namespace priv -{ -//////////////////////////////////////////////////////////// -/// \brief Specialization of RenderImageImpl using AGL P-Buffers -/// -//////////////////////////////////////////////////////////// -class RenderImageImplPBuffer : public RenderImageImpl, GlResource -{ -public : - - //////////////////////////////////////////////////////////// - /// \brief Default constructor - /// - //////////////////////////////////////////////////////////// - RenderImageImplPBuffer(); - - //////////////////////////////////////////////////////////// - /// \brief Destructor - /// - //////////////////////////////////////////////////////////// - ~RenderImageImplPBuffer(); - - //////////////////////////////////////////////////////////// - /// \brief Check whether the system supports P-Buffer or not - /// - /// \return True if P-Buffer render images are supported - /// - //////////////////////////////////////////////////////////// - static bool IsSupported(); - -private : - - //////////////////////////////////////////////////////////// - /// \brief Create the render image implementation - /// - /// \param width Width of the image to render to - /// \param height Height of the image to render to - /// \param textureId OpenGL texture identifier of the target image - /// \param depthBuffer Is a depth buffer requested? - /// - /// \return True if creation has been successful - /// - //////////////////////////////////////////////////////////// - virtual bool Create(unsigned int width, unsigned int height, unsigned int textureId, bool depthBuffer); - - //////////////////////////////////////////////////////////// - /// \brief Activate or deactivate the render image for rendering - /// - /// \param active True to activate, false to deactivate - /// - /// \return True on success, false on failure - /// - //////////////////////////////////////////////////////////// - virtual bool Activate(bool active); - - //////////////////////////////////////////////////////////// - /// \brief Update the pixels of the target texture - /// - /// \param textureId OpenGL identifier of the target texture - /// - //////////////////////////////////////////////////////////// - virtual void UpdateTexture(unsigned textureId); - - //////////////////////////////////////////////////////////// - // Member data - //////////////////////////////////////////////////////////// - AGLPbuffer myPBuffer; ///< P-Buffer - AGLContext myContext; ///< Associated OpenGL context - unsigned int myWidth; ///< Width of the P-Buffer - unsigned int myHeight; ///< Height of the P-Buffer -}; - -} // namespace priv - -} // namespace sf - - -#endif // SFML_RENDERIMAGEIMPLPBUFFER_HPP diff --git a/src/SFML/Graphics/RenderImage.cpp b/src/SFML/Graphics/RenderImage.cpp index 3c1770eb..be5a8738 100644 --- a/src/SFML/Graphics/RenderImage.cpp +++ b/src/SFML/Graphics/RenderImage.cpp @@ -27,7 +27,7 @@ //////////////////////////////////////////////////////////// #include #include -#include +#include #include @@ -44,7 +44,6 @@ myRenderImage(NULL) //////////////////////////////////////////////////////////// RenderImage::~RenderImage() { - SetActive(false); delete myRenderImage; } @@ -52,13 +51,6 @@ RenderImage::~RenderImage() //////////////////////////////////////////////////////////// bool RenderImage::Create(unsigned int width, unsigned int height, bool depthBuffer) { - // Make sure that render-images are supported - if (!IsAvailable()) - { - Err() << "Impossible to create render image (your system doesn't support this feature)" << std::endl; - return false; - } - // Create the image if (!myImage.Create(width, height)) { @@ -71,15 +63,15 @@ bool RenderImage::Create(unsigned int width, unsigned int height, bool depthBuff // Create the implementation delete myRenderImage; - if (priv::RenderImageImplFBO::IsSupported()) + if (priv::RenderImageImplFBO::IsAvailable()) { - // Use FBO + // Use frame-buffer object (FBO) myRenderImage = new priv::RenderImageImplFBO; } - else if (priv::RenderImageImplPBuffer::IsSupported()) + else { - // Use P-Buffer - myRenderImage = new priv::RenderImageImplPBuffer; + // Use default implementation + myRenderImage = new priv::RenderImageImplDefault; } // Initialize the render image @@ -150,14 +142,6 @@ const Image& RenderImage::GetImage() const } -//////////////////////////////////////////////////////////// -bool RenderImage::IsAvailable() -{ - return priv::RenderImageImplFBO::IsSupported() || - priv::RenderImageImplPBuffer::IsSupported(); -} - - //////////////////////////////////////////////////////////// bool RenderImage::Activate(bool active) { diff --git a/src/SFML/Graphics/RenderImageImplDefault.cpp b/src/SFML/Graphics/RenderImageImplDefault.cpp new file mode 100644 index 00000000..cb0f47b2 --- /dev/null +++ b/src/SFML/Graphics/RenderImageImplDefault.cpp @@ -0,0 +1,92 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include +#include + + +namespace sf +{ +namespace priv +{ +//////////////////////////////////////////////////////////// +RenderImageImplDefault::RenderImageImplDefault() : +myWidth (0), +myHeight (0), +myContext(0) +{ + +} + + +//////////////////////////////////////////////////////////// +RenderImageImplDefault::~RenderImageImplDefault() +{ + // Destroy the context + delete myContext; +} + + +//////////////////////////////////////////////////////////// +bool RenderImageImplDefault::Create(unsigned int width, unsigned int height, unsigned int, bool depthBuffer) +{ + // Store the dimensions + myWidth = width; + myHeight = height; + + // Create the in-memory OpenGL context + myContext = new Context(ContextSettings(depthBuffer ? 32 : 0, 0, 4), width, height); + + return true; +} + + +//////////////////////////////////////////////////////////// +bool RenderImageImplDefault::Activate(bool active) +{ + return myContext->SetActive(active); +} + + +//////////////////////////////////////////////////////////// +void RenderImageImplDefault::UpdateTexture(unsigned int textureId) +{ + GLint previous; + GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous)); + + // Copy the rendered pixels to the image + GLCheck(glBindTexture(GL_TEXTURE_2D, textureId)); + GLCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, myWidth, myHeight)); + + GLCheck(glBindTexture(GL_TEXTURE_2D, previous)); +} + +} // namespace priv + +} // namespace sf diff --git a/src/SFML/Graphics/Linux/RenderImageImplPBuffer.hpp b/src/SFML/Graphics/RenderImageImplDefault.hpp similarity index 78% rename from src/SFML/Graphics/Linux/RenderImageImplPBuffer.hpp rename to src/SFML/Graphics/RenderImageImplDefault.hpp index d092ff9e..a216c326 100644 --- a/src/SFML/Graphics/Linux/RenderImageImplPBuffer.hpp +++ b/src/SFML/Graphics/RenderImageImplDefault.hpp @@ -1,118 +1,107 @@ -//////////////////////////////////////////////////////////// -// -// SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) -// -// This software is provided 'as-is', without any express or implied warranty. -// In no event will the authors be held liable for any damages arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it freely, -// subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; -// you must not claim that you wrote the original software. -// If you use this software in a product, an acknowledgment -// in the product documentation would be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, -// and must not be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source distribution. -// -//////////////////////////////////////////////////////////// - -#ifndef SFML_RENDERIMAGEIMPLPBUFFER_HPP -#define SFML_RENDERIMAGEIMPLPBUFFER_HPP - -//////////////////////////////////////////////////////////// -// Headers -//////////////////////////////////////////////////////////// -#include -#include -#include -#include -#include - - -namespace sf -{ -namespace priv -{ -//////////////////////////////////////////////////////////// -/// \brief Specialization of RenderImageImpl using GLX P-Buffers -/// -//////////////////////////////////////////////////////////// -class RenderImageImplPBuffer : public RenderImageImpl, GlResource -{ -public : - - //////////////////////////////////////////////////////////// - /// \brief Default constructor - /// - //////////////////////////////////////////////////////////// - RenderImageImplPBuffer(); - - //////////////////////////////////////////////////////////// - /// \brief Destructor - /// - //////////////////////////////////////////////////////////// - ~RenderImageImplPBuffer(); - - //////////////////////////////////////////////////////////// - /// \brief Check whether the system supports P-Buffer or not - /// - /// \return True if P-Buffer render images are supported - /// - //////////////////////////////////////////////////////////// - static bool IsSupported(); - -private : - - //////////////////////////////////////////////////////////// - /// \brief Create the render image implementation - /// - /// \param width Width of the image to render to - /// \param height Height of the image to render to - /// \param textureId OpenGL texture identifier of the target image - /// \param depthBuffer Is a depth buffer requested? - /// - /// \return True if creation has been successful - /// - //////////////////////////////////////////////////////////// - virtual bool Create(unsigned int width, unsigned int height, unsigned int textureId, bool depthBuffer); - - //////////////////////////////////////////////////////////// - /// \brief Activate or deactivate the render image for rendering - /// - /// \param active True to activate, false to deactivate - /// - /// \return True on success, false on failure - /// - //////////////////////////////////////////////////////////// - virtual bool Activate(bool active); - - //////////////////////////////////////////////////////////// - /// \brief Update the pixels of the target texture - /// - /// \param textureId OpenGL identifier of the target texture - /// - //////////////////////////////////////////////////////////// - virtual void UpdateTexture(unsigned textureId); - - //////////////////////////////////////////////////////////// - // Member data - //////////////////////////////////////////////////////////// - ::Display* myDisplay; ///< Connection to the X display - GLXPbuffer myPBuffer; ///< P-Buffer - GLXContext myContext; ///< Associated OpenGL context - unsigned int myWidth; ///< Width of the P-Buffer - unsigned int myHeight; ///< Height of the P-Buffer -}; - -} // namespace priv - -} // namespace sf - - -#endif // SFML_RENDERIMAGEIMPLPBUFFER_HPP +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifndef SFML_RENDERIMAGEIMPLDEFAULT_HPP +#define SFML_RENDERIMAGEIMPLDEFAULT_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include + + +namespace sf +{ +namespace priv +{ +//////////////////////////////////////////////////////////// +/// \brief Default specialization of RenderImageImpl, +/// using a in-memory context +/// +//////////////////////////////////////////////////////////// +class RenderImageImplDefault : public RenderImageImpl, GlResource +{ +public : + + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + //////////////////////////////////////////////////////////// + RenderImageImplDefault(); + + //////////////////////////////////////////////////////////// + /// \brief Destructor + /// + //////////////////////////////////////////////////////////// + ~RenderImageImplDefault(); + +private : + + //////////////////////////////////////////////////////////// + /// \brief Create the render image implementation + /// + /// \param width Width of the image to render to + /// \param height Height of the image to render to + /// \param textureId OpenGL texture identifier of the target image + /// \param depthBuffer Is a depth buffer requested? + /// + /// \return True if creation has been successful + /// + //////////////////////////////////////////////////////////// + virtual bool Create(unsigned int width, unsigned int height, unsigned int textureId, bool depthBuffer); + + //////////////////////////////////////////////////////////// + /// \brief Activate or deactivate the render image for rendering + /// + /// \param active True to activate, false to deactivate + /// + /// \return True on success, false on failure + /// + //////////////////////////////////////////////////////////// + virtual bool Activate(bool active); + + //////////////////////////////////////////////////////////// + /// \brief Update the pixels of the target texture + /// + /// \param textureId OpenGL identifier of the target texture + /// + //////////////////////////////////////////////////////////// + virtual void UpdateTexture(unsigned textureId); + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + Context* myContext; ///< P-Buffer based context + unsigned int myWidth; ///< Width of the P-Buffer + unsigned int myHeight; ///< Height of the P-Buffer +}; + +} // namespace priv + +} // namespace sf + + +#endif // SFML_RENDERIMAGEIMPLDEFAULT_HPP diff --git a/src/SFML/Graphics/RenderImageImplFBO.cpp b/src/SFML/Graphics/RenderImageImplFBO.cpp index f3fe9f36..9f12b40d 100644 --- a/src/SFML/Graphics/RenderImageImplFBO.cpp +++ b/src/SFML/Graphics/RenderImageImplFBO.cpp @@ -62,11 +62,14 @@ RenderImageImplFBO::~RenderImageImplFBO() GLuint frameBuffer = static_cast(myFrameBuffer); GLCheck(glDeleteFramebuffersEXT(1, &frameBuffer)); } + + // Delete the context + delete myContext; } //////////////////////////////////////////////////////////// -bool RenderImageImplFBO::IsSupported() +bool RenderImageImplFBO::IsAvailable() { EnsureGlContext(); @@ -80,8 +83,8 @@ bool RenderImageImplFBO::IsSupported() //////////////////////////////////////////////////////////// bool RenderImageImplFBO::Create(unsigned int width, unsigned int height, unsigned int textureId, bool depthBuffer) { - // Activate the render-image's context - myContext.SetActive(true); + //Create the context + myContext = new Context; // Create the framebuffer object GLuint frameBuffer = 0; @@ -128,9 +131,7 @@ bool RenderImageImplFBO::Create(unsigned int width, unsigned int height, unsigne //////////////////////////////////////////////////////////// bool RenderImageImplFBO::Activate(bool active) { - myContext.SetActive(active); - - return true; + return myContext->SetActive(active); } //////////////////////////////////////////////////////////// diff --git a/src/SFML/Graphics/RenderImageImplFBO.hpp b/src/SFML/Graphics/RenderImageImplFBO.hpp index 0a4d3e02..d13a5a91 100644 --- a/src/SFML/Graphics/RenderImageImplFBO.hpp +++ b/src/SFML/Graphics/RenderImageImplFBO.hpp @@ -64,7 +64,7 @@ public : /// \return True if FBO render images are supported /// //////////////////////////////////////////////////////////// - static bool IsSupported(); + static bool IsAvailable(); private : @@ -102,9 +102,9 @@ private : //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// + Context* myContext; ///< Needs a separate OpenGL context for not messing up the other ones unsigned int myFrameBuffer; ///< OpenGL frame buffer object unsigned int myDepthBuffer; ///< Optional depth buffer attached to the frame buffer - Context myContext; ///< Needs a separate OpenGL context for not messing up the other ones }; } // namespace priv diff --git a/src/SFML/Graphics/RenderImageImplPBuffer.hpp b/src/SFML/Graphics/RenderImageImplPBuffer.hpp deleted file mode 100644 index be9735ee..00000000 --- a/src/SFML/Graphics/RenderImageImplPBuffer.hpp +++ /dev/null @@ -1,44 +0,0 @@ -//////////////////////////////////////////////////////////// -// -// SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) -// -// This software is provided 'as-is', without any express or implied warranty. -// In no event will the authors be held liable for any damages arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it freely, -// subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; -// you must not claim that you wrote the original software. -// If you use this software in a product, an acknowledgment -// in the product documentation would be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, -// and must not be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source distribution. -// -//////////////////////////////////////////////////////////// - - -//////////////////////////////////////////////////////////// -// Headers -//////////////////////////////////////////////////////////// -#include - - -#if defined(SFML_SYSTEM_WINDOWS) - - #include - -#elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD) - - #include - -#elif defined(SFML_SYSTEM_MACOS) - - #include - -#endif diff --git a/src/SFML/Graphics/Win32/RenderImageImplPBuffer.cpp b/src/SFML/Graphics/Win32/RenderImageImplPBuffer.cpp deleted file mode 100644 index 8ab75030..00000000 --- a/src/SFML/Graphics/Win32/RenderImageImplPBuffer.cpp +++ /dev/null @@ -1,196 +0,0 @@ -//////////////////////////////////////////////////////////// -// -// SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) -// -// This software is provided 'as-is', without any express or implied warranty. -// In no event will the authors be held liable for any damages arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it freely, -// subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; -// you must not claim that you wrote the original software. -// If you use this software in a product, an acknowledgment -// in the product documentation would be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, -// and must not be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source distribution. -// -//////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////// -// Headers -//////////////////////////////////////////////////////////// -#include -#include -#include -#include - - -namespace sf -{ -namespace priv -{ -//////////////////////////////////////////////////////////// -RenderImageImplPBuffer::RenderImageImplPBuffer() : -myPBuffer (NULL), -myDeviceContext(NULL), -myContext (NULL), -myWidth (0), -myHeight (0) -{ - -} - - -//////////////////////////////////////////////////////////// -RenderImageImplPBuffer::~RenderImageImplPBuffer() -{ - EnsureGlContext(); - - if (myContext) - wglDeleteContext(myContext); - - if (myPBuffer && myDeviceContext) - { - wglReleasePbufferDCARB(myPBuffer, myDeviceContext); - wglDestroyPbufferARB(myPBuffer); - } -} - - -//////////////////////////////////////////////////////////// -bool RenderImageImplPBuffer::IsSupported() -{ - EnsureGlContext(); - - // Make sure that GLEW is initialized - priv::EnsureGlewInit(); - - return WGLEW_ARB_pbuffer && WGLEW_ARB_pixel_format; -} - - -//////////////////////////////////////////////////////////// -bool RenderImageImplPBuffer::Create(unsigned int width, unsigned int height, unsigned int, bool depthBuffer) -{ - // Store the dimensions - myWidth = width; - myHeight = height; - - // Get the current HDC - HDC currentDC = wglGetCurrentDC(); - - // Define the minimum PBuffer attributes - int attributes[] = - { - WGL_SUPPORT_OPENGL_ARB, GL_TRUE, - WGL_DRAW_TO_PBUFFER_ARB, GL_TRUE, - WGL_RED_BITS_ARB, 8, - WGL_GREEN_BITS_ARB, 8, - WGL_BLUE_BITS_ARB, 8, - WGL_ALPHA_BITS_ARB, 8, - WGL_DEPTH_BITS_ARB, (depthBuffer ? 24 : 0), - WGL_DOUBLE_BUFFER_ARB, GL_FALSE, - 0 - }; - - // Select the best pixel format for our attributes - unsigned int nbFormats = 0; - int pixelFormat = -1; - wglChoosePixelFormatARB(currentDC, attributes, NULL, 1, &pixelFormat, &nbFormats); - - // Make sure that one pixel format has been found - if (nbFormats == 0) - { - Err() << "Impossible to create render image (failed to find a suitable pixel format for PBuffer)" << std::endl; - return false; - } - - // Create the P-Buffer and its OpenGL context - myPBuffer = wglCreatePbufferARB(currentDC, pixelFormat, width, height, NULL); - myDeviceContext = wglGetPbufferDCARB(myPBuffer); - myContext = wglCreateContext(myDeviceContext); - - // Check errors - if (!myPBuffer || !myDeviceContext || !myContext) - { - Err() << "Impossible to create render image (failed to create PBuffer)" << std::endl; - return false; - } - - // Check the actual size of the P-Buffer - int actualWidth, actualHeight; - wglQueryPbufferARB(myPBuffer, WGL_PBUFFER_WIDTH_ARB, &actualWidth); - wglQueryPbufferARB(myPBuffer, WGL_PBUFFER_HEIGHT_ARB, &actualHeight); - if ((actualWidth != static_cast(width)) || (actualHeight != static_cast(height))) - { - Err() << "Impossible to create render image (failed to match the requested size). " - << "Size: " << actualWidth << "x" << actualHeight << " - " - << "Requested: " << width << "x" << height - << std::endl; - return false; - } - - // Share the P-Buffer context with the current context - HGLRC currentContext = wglGetCurrentContext(); - if (currentContext) - { - wglMakeCurrent(NULL, NULL); - wglShareLists(currentContext, myContext); - wglMakeCurrent(currentDC, currentContext); - } - - return true; -} - - -//////////////////////////////////////////////////////////// -bool RenderImageImplPBuffer::Activate(bool active) -{ - if (active) - { - if (myDeviceContext && myContext) - { - if (wglGetCurrentContext() != myContext) - return wglMakeCurrent(myDeviceContext, myContext) != 0; - else - return true; - } - else - { - return false; - } - } - else - { - // 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 - // @todo fix - //return Context::SetReferenceActive(); - return true; - } -} - - -//////////////////////////////////////////////////////////// -void RenderImageImplPBuffer::UpdateTexture(unsigned int textureId) -{ - GLint previous; - GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous)); - - // Copy the rendered pixels to the image - GLCheck(glBindTexture(GL_TEXTURE_2D, textureId)); - GLCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, myWidth, myHeight)); - - GLCheck(glBindTexture(GL_TEXTURE_2D, previous)); -} - -} // namespace priv - -} // namespace sf diff --git a/src/SFML/Graphics/Win32/RenderImageImplPBuffer.hpp b/src/SFML/Graphics/Win32/RenderImageImplPBuffer.hpp deleted file mode 100644 index b137dce9..00000000 --- a/src/SFML/Graphics/Win32/RenderImageImplPBuffer.hpp +++ /dev/null @@ -1,117 +0,0 @@ -//////////////////////////////////////////////////////////// -// -// SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) -// -// This software is provided 'as-is', without any express or implied warranty. -// In no event will the authors be held liable for any damages arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it freely, -// subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; -// you must not claim that you wrote the original software. -// If you use this software in a product, an acknowledgment -// in the product documentation would be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, -// and must not be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source distribution. -// -//////////////////////////////////////////////////////////// - -#ifndef SFML_RENDERIMAGEIMPLPBUFFER_HPP -#define SFML_RENDERIMAGEIMPLPBUFFER_HPP - -//////////////////////////////////////////////////////////// -// Headers -//////////////////////////////////////////////////////////// -#include -#include -#include -#include - - -namespace sf -{ -namespace priv -{ -//////////////////////////////////////////////////////////// -/// \brief Specialization of RenderImageImpl using WGL P-Buffers -/// -//////////////////////////////////////////////////////////// -class RenderImageImplPBuffer : public RenderImageImpl, GlResource -{ -public : - - //////////////////////////////////////////////////////////// - /// \brief Default constructor - /// - //////////////////////////////////////////////////////////// - RenderImageImplPBuffer(); - - //////////////////////////////////////////////////////////// - /// \brief Destructor - /// - //////////////////////////////////////////////////////////// - ~RenderImageImplPBuffer(); - - //////////////////////////////////////////////////////////// - /// \brief Check whether the system supports P-Buffer or not - /// - /// \return True if P-Buffer render images are supported - /// - //////////////////////////////////////////////////////////// - static bool IsSupported(); - -private : - - //////////////////////////////////////////////////////////// - /// \brief Create the render image implementation - /// - /// \param width Width of the image to render to - /// \param height Height of the image to render to - /// \param textureId OpenGL texture identifier of the target image - /// \param depthBuffer Is a depth buffer requested? - /// - /// \return True if creation has been successful - /// - //////////////////////////////////////////////////////////// - virtual bool Create(unsigned int width, unsigned int height, unsigned int textureId, bool depthBuffer); - - //////////////////////////////////////////////////////////// - /// \brief Activate or deactivate the render image for rendering - /// - /// \param active True to activate, false to deactivate - /// - /// \return True on success, false on failure - /// - //////////////////////////////////////////////////////////// - virtual bool Activate(bool active); - - //////////////////////////////////////////////////////////// - /// \brief Update the pixels of the target texture - /// - /// \param textureId OpenGL identifier of the target texture - /// - //////////////////////////////////////////////////////////// - virtual void UpdateTexture(unsigned textureId); - - //////////////////////////////////////////////////////////// - // Member data - //////////////////////////////////////////////////////////// - HPBUFFERARB myPBuffer; ///< P-Buffer - HDC myDeviceContext; ///< Associated device context - HGLRC myContext; ///< Associated OpenGL context - unsigned int myWidth; ///< Width of the P-Buffer - unsigned int myHeight; ///< Height of the P-Buffer -}; - -} // namespace priv - -} // namespace sf - - -#endif // SFML_RENDERIMAGEIMPLPBUFFER_HPP diff --git a/src/SFML/Window/Context.cpp b/src/SFML/Window/Context.cpp index 220a0cfe..961c2508 100644 --- a/src/SFML/Window/Context.cpp +++ b/src/SFML/Window/Context.cpp @@ -42,16 +42,22 @@ Context::Context() //////////////////////////////////////////////////////////// Context::~Context() { - SetActive(false); delete myContext; } //////////////////////////////////////////////////////////// -void Context::SetActive(bool active) +bool Context::SetActive(bool active) { - myContext->SetActive(active); + return myContext->SetActive(active); } +//////////////////////////////////////////////////////////// +Context::Context(const ContextSettings& settings, unsigned int width, unsigned int height) +{ + myContext = priv::GlContext::New(settings, width, height); + SetActive(true); +} + } // namespace sf diff --git a/src/SFML/Window/GlContext.cpp b/src/SFML/Window/GlContext.cpp index 9fdf0264..18eab4f8 100644 --- a/src/SFML/Window/GlContext.cpp +++ b/src/SFML/Window/GlContext.cpp @@ -129,18 +129,38 @@ void GlContext::EnsureContext() //////////////////////////////////////////////////////////// GlContext* GlContext::New() { + // Make sure that there's an active context (context creation may need extensions, and thus a valid context) + EnsureContext(); + return new ContextType(sharedContext); } //////////////////////////////////////////////////////////// -GlContext* GlContext::New(const WindowImpl* owner, unsigned int bitsPerPixel, const ContextSettings& settings) +GlContext* GlContext::New(const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel) { // Make sure that there's an active context (context creation may need extensions, and thus a valid context) EnsureContext(); // Create the context - GlContext* context = new ContextType(sharedContext, owner, bitsPerPixel, settings); + GlContext* context = new ContextType(sharedContext, settings, owner, bitsPerPixel); + + // Enable antialiasing if needed + if (context->GetSettings().AntialiasingLevel > 0) + glEnable(GL_MULTISAMPLE_ARB); + + return context; +} + + +//////////////////////////////////////////////////////////// +GlContext* GlContext::New(const ContextSettings& settings, unsigned int width, unsigned int height) +{ + // Make sure that there's an active context (context creation may need extensions, and thus a valid context) + EnsureContext(); + + // Create the context + GlContext* context = new ContextType(sharedContext, settings, width, height); // Enable antialiasing if needed if (context->GetSettings().AntialiasingLevel > 0) diff --git a/src/SFML/Window/GlContext.hpp b/src/SFML/Window/GlContext.hpp index db7b44fb..dab762f3 100644 --- a/src/SFML/Window/GlContext.hpp +++ b/src/SFML/Window/GlContext.hpp @@ -94,14 +94,29 @@ public : /// This function automatically chooses the specialized class /// to use according to the OS. /// + /// \param settings Creation parameters /// \param owner Pointer to the owner window /// \param bitsPerPixel Pixel depth (in bits per pixel) - /// \param settings Creation parameters /// - /// \return Pointer to the created context (don't forget to delete it) + /// \return Pointer to the created context /// //////////////////////////////////////////////////////////// - static GlContext* New(const WindowImpl* owner, unsigned int bitsPerPixel, const ContextSettings& settings); + static GlContext* New(const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel); + + //////////////////////////////////////////////////////////// + /// \brief Create a new context that embeds its own rendering target + /// + /// This function automatically chooses the specialized class + /// to use according to the OS. + /// + /// \param settings Creation parameters + /// \param width Back buffer width + /// \param height Back buffer height + /// + /// \return Pointer to the created context + /// + //////////////////////////////////////////////////////////// + static GlContext* New(const ContextSettings& settings, unsigned int width, unsigned int height); public : diff --git a/src/SFML/Window/Linux/GlxContext.cpp b/src/SFML/Window/Linux/GlxContext.cpp index f441cbcf..7a40cf52 100644 --- a/src/SFML/Window/Linux/GlxContext.cpp +++ b/src/SFML/Window/Linux/GlxContext.cpp @@ -59,7 +59,7 @@ myOwnsWindow(true) 0, NULL); // Create the context - CreateContext(shared, VideoMode::GetDesktopMode().BitsPerPixel, ContextSettings(0, 0, 0)); + CreateContext(shared, VideoMode::GetDesktopMode().BitsPerPixel, ContextSettings()); // Activate the context SetActive(true); @@ -67,7 +67,7 @@ myOwnsWindow(true) //////////////////////////////////////////////////////////// -GlxContext::GlxContext(GlxContext* shared, const WindowImpl* owner, unsigned int bitsPerPixel, const ContextSettings& settings) : +GlxContext::GlxContext(GlxContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel) : myWindow (0), myContext (NULL), myOwnsWindow(false) @@ -87,6 +87,35 @@ myOwnsWindow(false) } +//////////////////////////////////////////////////////////// +GlxContext::GlxContext(GlxContext* shared, const ContextSettings& settings, unsigned int width, unsigned int height) : +myWindow (NULL), +myContext (NULL), +myOwnsWindow(true) +{ + // Open a connection with the X server + myDisplay = XOpenDisplay(NULL); + + // Create the hidden window + int screen = DefaultScreen(myDisplay); + myWindow = XCreateWindow(myDisplay, + RootWindow(myDisplay, screen), + 0, 0, + width, height, + 0, + DefaultDepth(myDisplay, screen), + InputOutput, + DefaultVisual(myDisplay, screen), + 0, NULL); + + // Create the context + CreateContext(shared, VideoMode::GetDesktopMode().BitsPerPixel, ContextSettings()); + + // Activate the context + SetActive(true); +} + + //////////////////////////////////////////////////////////// GlxContext::~GlxContext() { @@ -107,9 +136,7 @@ GlxContext::~GlxContext() // Close the connection with the X server if (myOwnsWindow) - { XCloseDisplay(myDisplay); - } } diff --git a/src/SFML/Window/Linux/GlxContext.hpp b/src/SFML/Window/Linux/GlxContext.hpp index fc50d2cd..87cd156f 100644 --- a/src/SFML/Window/Linux/GlxContext.hpp +++ b/src/SFML/Window/Linux/GlxContext.hpp @@ -46,7 +46,7 @@ class GlxContext : public GlContext public : //////////////////////////////////////////////////////////// - /// \brief Create a new context, not associated to a window + /// \brief Create a new default context /// /// \param shared Context to share the new one with (can be NULL) /// @@ -56,13 +56,24 @@ public : //////////////////////////////////////////////////////////// /// \brief Create a new context attached to a window /// - /// \param shared Context to share the new one with (can be NULL) - /// \param owner Pointer to the owner window - /// \param bitsPerPixel Pixel depth (in bits per pixel) + /// \param shared Context to share the new one with /// \param settings Creation parameters + /// \param owner Pointer to the owner window + /// \param bitsPerPixel Pixel depth, in bits per pixel /// //////////////////////////////////////////////////////////// - GlxContext(GlxContext* shared, const WindowImpl* owner, unsigned int bitsPerPixel, const ContextSettings& settings); + GlxContext(GlxContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel); + + //////////////////////////////////////////////////////////// + /// \brief Create a new context that embeds its own rendering target + /// + /// \param shared Context to share the new one with + /// \param settings Creation parameters + /// \param width Back buffer width, in pixels + /// \param height Back buffer height, in pixels + /// + //////////////////////////////////////////////////////////// + GlxContext(GlxContext* shared, const ContextSettings& settings, unsigned int width, unsigned int height); //////////////////////////////////////////////////////////// /// \brief Destructor diff --git a/src/SFML/Window/Win32/WglContext.cpp b/src/SFML/Window/Win32/WglContext.cpp index 3a65fb4f..ad8b3dc8 100644 --- a/src/SFML/Window/Win32/WglContext.cpp +++ b/src/SFML/Window/Win32/WglContext.cpp @@ -27,7 +27,6 @@ //////////////////////////////////////////////////////////// #include #include -#include #include #include #include @@ -56,7 +55,7 @@ myOwnsWindow (true) // Create the context if (myDeviceContext) - CreateContext(shared, VideoMode::GetDesktopMode().BitsPerPixel, ContextSettings(0, 0, 0)); + CreateContext(shared, VideoMode::GetDesktopMode().BitsPerPixel, ContextSettings()); // Activate the context SetActive(true); @@ -64,7 +63,7 @@ myOwnsWindow (true) //////////////////////////////////////////////////////////// -WglContext::WglContext(WglContext* shared, const WindowImpl* owner, unsigned int bitsPerPixel, const ContextSettings& settings) : +WglContext::WglContext(WglContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel) : myWindow (NULL), myDeviceContext(NULL), myContext (NULL), @@ -83,6 +82,32 @@ myOwnsWindow (false) } +//////////////////////////////////////////////////////////// +WglContext::WglContext(WglContext* shared, const ContextSettings& settings, unsigned int width, unsigned int height) : +myWindow (NULL), +myDeviceContext(NULL), +myContext (NULL), +myOwnsWindow (true) +{ + // The target of the context is a hidden window. + // We can't create a memory DC (the resulting context wouldn't be compatible + // with other contexts), and we don't add the extra complexity of P-Buffers; + // we can still support them in the future if this solution is not good enough. + + // Create the hidden window + myWindow = CreateWindowA("STATIC", "", WS_POPUP | WS_DISABLED, 0, 0, width, height, NULL, NULL, GetModuleHandle(NULL), NULL); + ShowWindow(myWindow, SW_HIDE); + myDeviceContext = GetDC(myWindow); + + // Create the context + if (myDeviceContext) + CreateContext(shared, VideoMode::GetDesktopMode().BitsPerPixel, settings); + + // Activate the context + SetActive(true); +} + + //////////////////////////////////////////////////////////// WglContext::~WglContext() { @@ -94,8 +119,8 @@ WglContext::~WglContext() wglDeleteContext(myContext); } - // Release the DC - if (myWindow && myDeviceContext) + // Destroy the device context + if (myDeviceContext) ReleaseDC(myWindow, myDeviceContext); // Destroy the window if we own it diff --git a/src/SFML/Window/Win32/WglContext.hpp b/src/SFML/Window/Win32/WglContext.hpp index b0bb5333..7b315e36 100644 --- a/src/SFML/Window/Win32/WglContext.hpp +++ b/src/SFML/Window/Win32/WglContext.hpp @@ -29,7 +29,7 @@ // Headers //////////////////////////////////////////////////////////// #include -#include +#include namespace sf @@ -45,7 +45,7 @@ class WglContext : public GlContext public : //////////////////////////////////////////////////////////// - /// \brief Create a new context, not associated to a window + /// \brief Create a new default context /// /// \param shared Context to share the new one with (can be NULL) /// @@ -55,13 +55,24 @@ public : //////////////////////////////////////////////////////////// /// \brief Create a new context attached to a window /// - /// \param shared Context to share the new one with (can be NULL) - /// \param owner Pointer to the owner window - /// \param bitsPerPixel Pixel depth (in bits per pixel) + /// \param shared Context to share the new one with /// \param settings Creation parameters + /// \param owner Pointer to the owner window + /// \param bitsPerPixel Pixel depth, in bits per pixel /// //////////////////////////////////////////////////////////// - WglContext(WglContext* shared, const WindowImpl* owner, unsigned int bitsPerPixel, const ContextSettings& settings); + WglContext(WglContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel); + + //////////////////////////////////////////////////////////// + /// \brief Create a new context that embeds its own rendering target + /// + /// \param shared Context to share the new one with + /// \param settings Creation parameters + /// \param width Back buffer width, in pixels + /// \param height Back buffer height, in pixels + /// + //////////////////////////////////////////////////////////// + WglContext(WglContext* shared, const ContextSettings& settings, unsigned int width, unsigned int height); //////////////////////////////////////////////////////////// /// \brief Destructor @@ -102,9 +113,9 @@ private : //////////////////////////////////////////////////////////// /// \brief Create the context /// - /// \param shared Context to share the new one with (can be NULL) - /// \param bitsPerPixel Pixel depth, in bits per pixel - /// \param settings Creation parameters + /// \param shared Context to share the new one with (can be NULL) + /// \param bitsPerPixel Pixel depth, in bits per pixel + /// \param settings Creation parameters /// //////////////////////////////////////////////////////////// void CreateContext(WglContext* shared, unsigned int bitsPerPixel, const ContextSettings& settings); @@ -113,9 +124,9 @@ private : // Member data //////////////////////////////////////////////////////////// HWND myWindow; ///< Window to which the context is attached - HDC myDeviceContext; ///< Device context of the window + HDC myDeviceContext; ///< Device context associated to the context HGLRC myContext; ///< OpenGL context - bool myOwnsWindow; ///< Did we create the host window? + bool myOwnsWindow; ///< Do we own the target window? }; } // namespace priv diff --git a/src/SFML/Window/Window.cpp b/src/SFML/Window/Window.cpp index 0454dfbc..944b0b9d 100644 --- a/src/SFML/Window/Window.cpp +++ b/src/SFML/Window/Window.cpp @@ -126,7 +126,7 @@ void Window::Create(VideoMode mode, const std::string& title, unsigned long styl myWindow = priv::WindowImpl::New(mode, title, style); // Recreate the context - myContext = priv::GlContext::New(myWindow, mode.BitsPerPixel, settings); + myContext = priv::GlContext::New(settings, myWindow, mode.BitsPerPixel); // Perform common initializations Initialize(); @@ -143,7 +143,7 @@ void Window::Create(WindowHandle handle, const ContextSettings& settings) myWindow = priv::WindowImpl::New(handle); // Recreate the context - myContext = priv::GlContext::New(myWindow, VideoMode::GetDesktopMode().BitsPerPixel, settings); + myContext = priv::GlContext::New(settings, myWindow, VideoMode::GetDesktopMode().BitsPerPixel); // Perform common initializations Initialize();