Replaced the P-Buffer implementation of RenderImage with a generic "in-memory context" one
This commit is contained in:
parent
3acacc8049
commit
92f70b32e9
@ -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 :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
@ -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 :
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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")
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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)
|
||||
{
|
||||
|
92
src/SFML/Graphics/RenderImageImplDefault.cpp
Normal file
92
src/SFML/Graphics/RenderImageImplDefault.cpp
Normal 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
|
@ -22,17 +22,15 @@
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SFML_RENDERIMAGEIMPLPBUFFER_HPP
|
||||
#define SFML_RENDERIMAGEIMPLPBUFFER_HPP
|
||||
#ifndef SFML_RENDERIMAGEIMPLDEFAULT_HPP
|
||||
#define SFML_RENDERIMAGEIMPLDEFAULT_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/RenderImageImpl.hpp>
|
||||
#include <SFML/Window/GlResource.hpp>
|
||||
#include <GL/glew.h>
|
||||
#include <GL/glxew.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <SFML/Window/Context.hpp>
|
||||
|
||||
|
||||
namespace sf
|
||||
@ -40,10 +38,11 @@ namespace sf
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Specialization of RenderImageImpl using GLX P-Buffers
|
||||
/// \brief Default specialization of RenderImageImpl,
|
||||
/// using a in-memory context
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class RenderImageImplPBuffer : public RenderImageImpl, GlResource
|
||||
class RenderImageImplDefault : public RenderImageImpl, GlResource
|
||||
{
|
||||
public :
|
||||
|
||||
@ -51,21 +50,13 @@ public :
|
||||
/// \brief Default constructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
RenderImageImplPBuffer();
|
||||
RenderImageImplDefault();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \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();
|
||||
~RenderImageImplDefault();
|
||||
|
||||
private :
|
||||
|
||||
@ -103,9 +94,7 @@ private :
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
::Display* myDisplay; ///< Connection to the X display
|
||||
GLXPbuffer myPBuffer; ///< P-Buffer
|
||||
GLXContext myContext; ///< Associated OpenGL context
|
||||
Context* myContext; ///< P-Buffer based context
|
||||
unsigned int myWidth; ///< Width of the P-Buffer
|
||||
unsigned int myHeight; ///< Height of the P-Buffer
|
||||
};
|
||||
@ -115,4 +104,4 @@ private :
|
||||
} // namespace sf
|
||||
|
||||
|
||||
#endif // SFML_RENDERIMAGEIMPLPBUFFER_HPP
|
||||
#endif // SFML_RENDERIMAGEIMPLDEFAULT_HPP
|
@ -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);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 :
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user