Replaced the P-Buffer implementation of RenderImage with a generic "in-memory context" one

This commit is contained in:
Laurent Gomila 2011-04-04 08:20:03 +02:00
parent 3acacc8049
commit 92f70b32e9
23 changed files with 386 additions and 1103 deletions

View File

@ -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 :
////////////////////////////////////////////////////////////

View File

@ -30,6 +30,7 @@
////////////////////////////////////////////////////////////
#include <SFML/Config.hpp>
#include <SFML/Window/GlResource.hpp>
#include <SFML/Window/ContextSettings.hpp>
#include <SFML/System/NonCopyable.hpp>
@ -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 :

View File

@ -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),

View File

@ -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")

View File

@ -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 <SFML/Graphics/Linux/RenderImageImplPBuffer.hpp>
#include <SFML/Graphics/GLCheck.hpp>
#include <SFML/Window/Context.hpp>
#include <SFML/System/Err.hpp>
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

View File

@ -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 <SFML/Graphics/OSX/RenderImageImplPBuffer.hpp>
#include <SFML/Graphics/GLCheck.hpp>
#include <SFML/Window/Context.hpp>
#include <SFML/System/Err.hpp>
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

View File

@ -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 <SFML/Graphics/RenderImageImpl.hpp>
#include <SFML/Window/GlResource.hpp>
#include <GL/glew.h>
#include <AGL/agl.h>
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

View File

@ -27,7 +27,7 @@
////////////////////////////////////////////////////////////
#include <SFML/Graphics/RenderImage.hpp>
#include <SFML/Graphics/RenderImageImplFBO.hpp>
#include <SFML/Graphics/RenderImageImplPBuffer.hpp>
#include <SFML/Graphics/RenderImageImplDefault.hpp>
#include <SFML/System/Err.hpp>
@ -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)
{

View File

@ -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 <SFML/Graphics/RenderImageImplDefault.hpp>
#include <SFML/Graphics/GLCheck.hpp>
#include <SFML/Window/Context.hpp>
#include <SFML/System/Err.hpp>
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

View File

@ -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 <SFML/Graphics/RenderImageImpl.hpp>
#include <SFML/Window/GlResource.hpp>
#include <GL/glew.h>
#include <GL/glxew.h>
#include <X11/Xlib.h>
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 <SFML/Graphics/RenderImageImpl.hpp>
#include <SFML/Window/GlResource.hpp>
#include <SFML/Window/Context.hpp>
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

View File

@ -62,11 +62,14 @@ RenderImageImplFBO::~RenderImageImplFBO()
GLuint frameBuffer = static_cast<GLuint>(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);
}
////////////////////////////////////////////////////////////

View File

@ -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

View File

@ -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 <SFML/Config.hpp>
#if defined(SFML_SYSTEM_WINDOWS)
#include <SFML/Graphics/Win32/RenderImageImplPBuffer.hpp>
#elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD)
#include <SFML/Graphics/Linux/RenderImageImplPBuffer.hpp>
#elif defined(SFML_SYSTEM_MACOS)
#include <SFML/Graphics/OSX/RenderImageImplPBuffer.hpp>
#endif

View File

@ -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 <SFML/Graphics/Win32/RenderImageImplPBuffer.hpp>
#include <SFML/Graphics/GLCheck.hpp>
#include <SFML/Window/Context.hpp>
#include <SFML/System/Err.hpp>
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<int>(width)) || (actualHeight != static_cast<int>(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

View File

@ -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 <SFML/Graphics/RenderImageImpl.hpp>
#include <SFML/Window/GlResource.hpp>
#include <GL/glew.h>
#include <GL/wglew.h>
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

View File

@ -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

View File

@ -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)

View File

@ -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 :

View File

@ -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);
}
}

View File

@ -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

View File

@ -27,7 +27,6 @@
////////////////////////////////////////////////////////////
#include <SFML/Window/Win32/WglContext.hpp>
#include <SFML/Window/WindowImpl.hpp>
#include <SFML/OpenGL.hpp>
#include <SFML/Window/glext/wglext.h>
#include <SFML/System/Lock.hpp>
#include <SFML/System/Mutex.hpp>
@ -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

View File

@ -29,7 +29,7 @@
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/GlContext.hpp>
#include <windows.h>
#include <SFML/OpenGL.hpp>
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

View File

@ -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();