ATI fix!
git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1809 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
parent
6cf2303484
commit
a94ed51702
25 changed files with 496 additions and 229 deletions
|
@ -84,6 +84,8 @@ Image::~Image()
|
|||
// Destroy the OpenGL texture
|
||||
if (myTexture)
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
GLuint Texture = static_cast<GLuint>(myTexture);
|
||||
GLCheck(glDeleteTextures(1, &Texture));
|
||||
}
|
||||
|
@ -410,6 +412,8 @@ void Image::UpdatePixels(const Uint8* pixels)
|
|||
{
|
||||
if (pixels && myTexture)
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
GLint previous;
|
||||
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
|
||||
|
||||
|
@ -468,6 +472,8 @@ void Image::SetSmooth(bool smooth)
|
|||
|
||||
if (myTexture)
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
GLint previous;
|
||||
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
|
||||
|
||||
|
@ -535,6 +541,8 @@ FloatRect Image::GetTexCoords(const IntRect& rect) const
|
|||
////////////////////////////////////////////////////////////
|
||||
unsigned int Image::GetMaximumSize()
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
GLint size;
|
||||
GLCheck(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size));
|
||||
|
||||
|
@ -565,6 +573,8 @@ Image& Image::operator =(const Image& right)
|
|||
////////////////////////////////////////////////////////////
|
||||
unsigned int Image::GetValidSize(unsigned int size)
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
// Make sure that GLEW is initialized
|
||||
priv::EnsureGlewInit();
|
||||
|
||||
|
@ -613,6 +623,8 @@ bool Image::CreateTexture(unsigned int width, unsigned int height)
|
|||
myTextureWidth = textureWidth;
|
||||
myTextureHeight = textureHeight;
|
||||
|
||||
EnsureGlContext();
|
||||
|
||||
// Create the OpenGL texture if it doesn't exist yet
|
||||
if (!myTexture)
|
||||
{
|
||||
|
@ -645,6 +657,8 @@ void Image::EnsureTextureUpdate() const
|
|||
{
|
||||
if (myTexture && !myPixels.empty())
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
GLint previous;
|
||||
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
|
||||
|
||||
|
@ -666,6 +680,8 @@ void Image::EnsureArrayUpdate() const
|
|||
{
|
||||
if (!myArrayUpdated)
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
// Save the previous texture
|
||||
GLint previous;
|
||||
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
|
||||
|
|
|
@ -49,6 +49,8 @@ myHeight (0)
|
|||
////////////////////////////////////////////////////////////
|
||||
RenderImageImplPBuffer::~RenderImageImplPBuffer()
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
if (myContext)
|
||||
glXDestroyContext(myDisplay, myContext);
|
||||
|
||||
|
@ -56,20 +58,18 @@ RenderImageImplPBuffer::~RenderImageImplPBuffer()
|
|||
glXDestroyGLXPbufferSGIX(myDisplay, myPBuffer);
|
||||
|
||||
XCloseDisplay(myDisplay);
|
||||
|
||||
// This is to make sure that another valid context is made
|
||||
// active after we destroy the P-Buffer's one
|
||||
Context::SetReferenceActive();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderImageImplPBuffer::IsSupported()
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
// Make sure that GLEW is initialized
|
||||
EnsureGlewInit();
|
||||
|
||||
return glxewIsSupported("GLX_SGIX_pbuffer");
|
||||
return GLXEW_SGIX_pbuffer && GLXEW_SGIX_fbconfig;
|
||||
}
|
||||
|
||||
|
||||
|
@ -182,7 +182,9 @@ bool RenderImageImplPBuffer::Activate(bool active)
|
|||
// To deactivate the P-Buffer's context, we actually activate
|
||||
// another one so that we make sure that there is always an
|
||||
// active context for subsequent graphics operations
|
||||
return Context::SetReferenceActive();
|
||||
// @odo fixme
|
||||
//return Context::SetReferenceActive();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,17 +192,14 @@ bool RenderImageImplPBuffer::Activate(bool active)
|
|||
////////////////////////////////////////////////////////////
|
||||
void RenderImageImplPBuffer::UpdateTexture(unsigned int textureId)
|
||||
{
|
||||
if (Activate(true))
|
||||
{
|
||||
GLint previous;
|
||||
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
|
||||
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));
|
||||
// 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));
|
||||
}
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
|
||||
}
|
||||
|
||||
} // namespace priv
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/RenderImageImpl.hpp>
|
||||
#include <SFML/Window/GlResource.hpp>
|
||||
#include <GL/glew.h>
|
||||
#include <GL/glxew.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
@ -42,7 +43,7 @@ namespace priv
|
|||
/// \brief Specialization of RenderImageImpl using GLX P-Buffers
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class RenderImageImplPBuffer : public RenderImageImpl
|
||||
class RenderImageImplPBuffer : public RenderImageImpl, GlResource
|
||||
{
|
||||
public :
|
||||
|
||||
|
|
|
@ -66,16 +66,14 @@ RenderImageImplPBuffer::~RenderImageImplPBuffer()
|
|||
<< aglGetError()
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
// This is to make sure that another valid context is made
|
||||
// active after we destroy the P-Buffer's one
|
||||
Context::SetReferenceActive();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderImageImplPBuffer::IsSupported()
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
const GLubyte* strExt = glGetString(GL_EXTENSIONS);
|
||||
GLboolean isSupported = gluCheckExtension((const GLubyte*)"GL_APPLE_pixel_buffer", strExt);
|
||||
|
||||
|
@ -164,21 +162,24 @@ bool RenderImageImplPBuffer::Create(unsigned int width, unsigned int height, uns
|
|||
////////////////////////////////////////////////////////////
|
||||
bool RenderImageImplPBuffer::Activate(bool active)
|
||||
{
|
||||
if (active) {
|
||||
if (!myContext || !myPBuffer) { // Not created yet.
|
||||
if (active)
|
||||
{
|
||||
if (!myContext || !myPBuffer) // Not created yet.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aglGetCurrentContext() == myContext) {
|
||||
if (aglGetCurrentContext() == myContext)
|
||||
return true;
|
||||
} else {
|
||||
else
|
||||
return aglSetCurrentContext(myContext);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
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
|
||||
return Context::SetReferenceActive();
|
||||
// @todo fixme
|
||||
// return Context::SetReferenceActive();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,17 +187,14 @@ bool RenderImageImplPBuffer::Activate(bool active)
|
|||
////////////////////////////////////////////////////////////
|
||||
void RenderImageImplPBuffer::UpdateTexture(unsigned int textureId)
|
||||
{
|
||||
if (Activate(true))
|
||||
{
|
||||
GLint previous;
|
||||
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
|
||||
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));
|
||||
// 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));
|
||||
}
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
|
||||
}
|
||||
|
||||
} // namespace priv
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/RenderImageImpl.hpp>
|
||||
#include <SFML/Window/GlResource.hpp>
|
||||
#include <GL/glew.h>
|
||||
#include <AGL/agl.h>
|
||||
|
||||
|
@ -41,7 +42,7 @@ namespace priv
|
|||
/// \brief Specialization of RenderImageImpl using AGL P-Buffers
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class RenderImageImplPBuffer : public RenderImageImpl
|
||||
class RenderImageImplPBuffer : public RenderImageImpl, GlResource
|
||||
{
|
||||
public :
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ myRenderImage(NULL)
|
|||
////////////////////////////////////////////////////////////
|
||||
RenderImage::~RenderImage()
|
||||
{
|
||||
SetActive(false);
|
||||
delete myRenderImage;
|
||||
}
|
||||
|
||||
|
@ -117,7 +118,7 @@ bool RenderImage::SetActive(bool active)
|
|||
void RenderImage::Display()
|
||||
{
|
||||
// Update the target image
|
||||
if (myRenderImage)
|
||||
if (SetActive(true))
|
||||
{
|
||||
myRenderImage->UpdateTexture(myImage.myTexture);
|
||||
|
||||
|
|
|
@ -47,6 +47,8 @@ myDepthBuffer(0)
|
|||
////////////////////////////////////////////////////////////
|
||||
RenderImageImplFBO::~RenderImageImplFBO()
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
// Destroy the depth buffer
|
||||
if (myDepthBuffer)
|
||||
{
|
||||
|
@ -66,6 +68,8 @@ RenderImageImplFBO::~RenderImageImplFBO()
|
|||
////////////////////////////////////////////////////////////
|
||||
bool RenderImageImplFBO::IsSupported()
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
// Make sure that GLEW is initialized
|
||||
priv::EnsureGlewInit();
|
||||
|
||||
|
@ -76,6 +80,9 @@ 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 framebuffer object
|
||||
GLuint frameBuffer = 0;
|
||||
GLCheck(glGenFramebuffersEXT(1, &frameBuffer));
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/RenderImageImpl.hpp>
|
||||
#include <SFML/Window/Context.hpp>
|
||||
#include <SFML/Window/GlResource.hpp>
|
||||
|
||||
|
||||
namespace sf
|
||||
|
@ -41,7 +42,7 @@ namespace priv
|
|||
/// Frame Buffer Object OpenGL extension
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class RenderImageImplFBO : public RenderImageImpl
|
||||
class RenderImageImplFBO : public RenderImageImpl, GlResource
|
||||
{
|
||||
public :
|
||||
|
||||
|
|
|
@ -35,12 +35,6 @@
|
|||
|
||||
namespace sf
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
// Static member data
|
||||
////////////////////////////////////////////////////////////
|
||||
const Image Shader::CurrentTexture;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Shader::Shader() :
|
||||
myShaderProgram (0),
|
||||
|
@ -66,6 +60,8 @@ myFragmentShader(copy.myFragmentShader)
|
|||
////////////////////////////////////////////////////////////
|
||||
Shader::~Shader()
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
// Destroy effect program
|
||||
if (myShaderProgram)
|
||||
GLCheck(glDeleteObjectARB(myShaderProgram));
|
||||
|
@ -109,6 +105,8 @@ void Shader::SetParameter(const std::string& name, float x)
|
|||
{
|
||||
if (myShaderProgram)
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
// Enable program
|
||||
GLhandleARB program = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
|
||||
GLCheck(glUseProgramObjectARB(myShaderProgram));
|
||||
|
@ -131,6 +129,8 @@ void Shader::SetParameter(const std::string& name, float x, float y)
|
|||
{
|
||||
if (myShaderProgram)
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
// Enable program
|
||||
GLhandleARB program = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
|
||||
GLCheck(glUseProgramObjectARB(myShaderProgram));
|
||||
|
@ -153,6 +153,8 @@ void Shader::SetParameter(const std::string& name, float x, float y, float z)
|
|||
{
|
||||
if (myShaderProgram)
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
// Enable program
|
||||
GLhandleARB program = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
|
||||
GLCheck(glUseProgramObjectARB(myShaderProgram));
|
||||
|
@ -175,6 +177,8 @@ void Shader::SetParameter(const std::string& name, float x, float y, float z, fl
|
|||
{
|
||||
if (myShaderProgram)
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
// Enable program
|
||||
GLhandleARB program = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
|
||||
GLCheck(glUseProgramObjectARB(myShaderProgram));
|
||||
|
@ -211,16 +215,9 @@ void Shader::SetTexture(const std::string& name, const Image& texture)
|
|||
{
|
||||
if (myShaderProgram)
|
||||
{
|
||||
// Check if there is a texture unit available
|
||||
GLint maxUnits;
|
||||
GLCheck(glGetIntegerv(GL_MAX_TEXTURE_COORDS_ARB, &maxUnits));
|
||||
if (myTextures.size() + 1 >= static_cast<std::size_t>(maxUnits))
|
||||
{
|
||||
Err() << "Impossible to use texture \"" << name << "\" for shader: all available texture units are used" << std::endl;
|
||||
return;
|
||||
}
|
||||
EnsureGlContext();
|
||||
|
||||
// Make sure the given name is a valid variable in the effect
|
||||
// Find the location of the variable in the shader
|
||||
int location = glGetUniformLocationARB(myShaderProgram, name.c_str());
|
||||
if (location == -1)
|
||||
{
|
||||
|
@ -228,11 +225,41 @@ void Shader::SetTexture(const std::string& name, const Image& texture)
|
|||
return;
|
||||
}
|
||||
|
||||
// Store the texture for later use
|
||||
if (&texture != &CurrentTexture)
|
||||
// Store the location -> texture mapping
|
||||
TextureTable::iterator it = myTextures.find(location);
|
||||
if (it == myTextures.end())
|
||||
{
|
||||
// New entry, make sure there are enough texture units
|
||||
GLint maxUnits;
|
||||
GLCheck(glGetIntegerv(GL_MAX_TEXTURE_COORDS_ARB, &maxUnits));
|
||||
if (myTextures.size() + 1 >= static_cast<std::size_t>(maxUnits))
|
||||
{
|
||||
Err() << "Impossible to use texture \"" << name << "\" for shader: all available texture units are used" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
myTextures[location] = &texture;
|
||||
}
|
||||
else
|
||||
myCurrentTexture = location;
|
||||
{
|
||||
// Location already used, just replace the texture
|
||||
it->second = &texture;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Shader::SetCurrentTexture(const std::string& name)
|
||||
{
|
||||
if (myShaderProgram)
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
// Find the location of the variable in the shader
|
||||
int myCurrentTexture = glGetUniformLocationARB(myShaderProgram, name.c_str());
|
||||
if (myCurrentTexture == -1)
|
||||
Err() << "Texture \"" << name << "\" not found in shader" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,6 +269,8 @@ void Shader::Bind() const
|
|||
{
|
||||
if (myShaderProgram)
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
// Enable the program
|
||||
GLCheck(glUseProgramObjectARB(myShaderProgram));
|
||||
|
||||
|
@ -258,6 +287,8 @@ void Shader::Bind() const
|
|||
////////////////////////////////////////////////////////////
|
||||
void Shader::Unbind() const
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
GLCheck(glUseProgramObjectARB(0));
|
||||
}
|
||||
|
||||
|
@ -279,6 +310,8 @@ Shader& Shader::operator =(const Shader& right)
|
|||
////////////////////////////////////////////////////////////
|
||||
bool Shader::IsAvailable()
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
// Make sure that GLEW is initialized
|
||||
priv::EnsureGlewInit();
|
||||
|
||||
|
@ -292,6 +325,8 @@ bool Shader::IsAvailable()
|
|||
////////////////////////////////////////////////////////////
|
||||
bool Shader::CompileProgram()
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
// First make sure that we can use shaders
|
||||
if (!IsAvailable())
|
||||
{
|
||||
|
@ -300,9 +335,6 @@ bool Shader::CompileProgram()
|
|||
return false;
|
||||
}
|
||||
|
||||
// Make sure that GLEW is initialized (extra safety -- it is already done in IsAvailable())
|
||||
priv::EnsureGlewInit();
|
||||
|
||||
// Destroy the shader if it was already created
|
||||
if (myShaderProgram)
|
||||
GLCheck(glDeleteObjectARB(myShaderProgram));
|
||||
|
@ -398,7 +430,7 @@ void Shader::BindTextures() const
|
|||
GLCheck(glUniform1iARB(it->first, index));
|
||||
GLCheck(glActiveTextureARB(GL_TEXTURE0_ARB + index));
|
||||
it->second->Bind();
|
||||
it++;
|
||||
++it;
|
||||
}
|
||||
|
||||
// Make sure that the texture unit which is left active is the number 0
|
||||
|
|
|
@ -50,6 +50,8 @@ myHeight (0)
|
|||
////////////////////////////////////////////////////////////
|
||||
RenderImageImplPBuffer::~RenderImageImplPBuffer()
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
if (myContext)
|
||||
wglDeleteContext(myContext);
|
||||
|
||||
|
@ -58,16 +60,14 @@ RenderImageImplPBuffer::~RenderImageImplPBuffer()
|
|||
wglReleasePbufferDCARB(myPBuffer, myDeviceContext);
|
||||
wglDestroyPbufferARB(myPBuffer);
|
||||
}
|
||||
|
||||
// This is to make sure that another valid context is made
|
||||
// active after we destroy the P-Buffer's one
|
||||
Context::SetReferenceActive();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderImageImplPBuffer::IsSupported()
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
// Make sure that GLEW is initialized
|
||||
priv::EnsureGlewInit();
|
||||
|
||||
|
@ -171,7 +171,9 @@ bool RenderImageImplPBuffer::Activate(bool active)
|
|||
// To deactivate the P-Buffer's context, we actually activate
|
||||
// another one so that we make sure that there is always an
|
||||
// active context for subsequent graphics operations
|
||||
return Context::SetReferenceActive();
|
||||
// @todo fix
|
||||
//return Context::SetReferenceActive();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -179,17 +181,14 @@ bool RenderImageImplPBuffer::Activate(bool active)
|
|||
////////////////////////////////////////////////////////////
|
||||
void RenderImageImplPBuffer::UpdateTexture(unsigned int textureId)
|
||||
{
|
||||
if (Activate(true))
|
||||
{
|
||||
GLint previous;
|
||||
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
|
||||
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));
|
||||
// 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));
|
||||
}
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
|
||||
}
|
||||
|
||||
} // namespace priv
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/RenderImageImpl.hpp>
|
||||
#include <SFML/Window/GlResource.hpp>
|
||||
#include <GL/glew.h>
|
||||
#include <GL/wglew.h>
|
||||
|
||||
|
@ -41,7 +42,7 @@ namespace priv
|
|||
/// \brief Specialization of RenderImageImpl using WGL P-Buffers
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class RenderImageImplPBuffer : public RenderImageImpl
|
||||
class RenderImageImplPBuffer : public RenderImageImpl, GlResource
|
||||
{
|
||||
public :
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ set(SRC
|
|||
${INCROOT}/Context.hpp
|
||||
${SRCROOT}/GlContext.cpp
|
||||
${SRCROOT}/GlContext.hpp
|
||||
${SRCROOT}/GlResource.cpp
|
||||
${INCROOT}/GlResource.hpp
|
||||
${INCROOT}/ContextSettings.hpp
|
||||
${INCROOT}/Event.hpp
|
||||
${SRCROOT}/Input.cpp
|
||||
|
@ -51,24 +53,24 @@ else() # MACOSX
|
|||
set(SRC
|
||||
${SRC}
|
||||
${SRCROOT}/OSX/cpp_objc_conversion.h
|
||||
${SRCROOT}/OSX/cpp_objc_conversion.mm
|
||||
${SRCROOT}/OSX/cg_sf_conversion.hpp
|
||||
${SRCROOT}/OSX/cpp_objc_conversion.mm
|
||||
${SRCROOT}/OSX/cg_sf_conversion.hpp
|
||||
${SRCROOT}/OSX/cg_sf_conversion.cpp
|
||||
${SRCROOT}/OSX/Joystick.cpp
|
||||
${SRCROOT}/OSX/Joystick.hpp
|
||||
${SRCROOT}/OSX/SFApplication.h
|
||||
${SRCROOT}/OSX/SFApplication.m
|
||||
${SRCROOT}/OSX/SFContext.hpp
|
||||
${SRCROOT}/OSX/SFContext.mm
|
||||
${SRCROOT}/OSX/SFOpenGLView.h
|
||||
${SRCROOT}/OSX/SFOpenGLView.mm
|
||||
${SRCROOT}/OSX/SFWindow.h
|
||||
${SRCROOT}/OSX/SFWindow.m
|
||||
${SRCROOT}/OSX/SFWindowController.h
|
||||
${SRCROOT}/OSX/SFWindowController.mm
|
||||
${SRCROOT}/OSX/VideoModeImpl.cpp
|
||||
${SRCROOT}/OSX/WindowImplCocoa.hpp
|
||||
${SRCROOT}/OSX/WindowImplCocoa.mm
|
||||
${SRCROOT}/OSX/Joystick.hpp
|
||||
${SRCROOT}/OSX/SFApplication.h
|
||||
${SRCROOT}/OSX/SFApplication.m
|
||||
${SRCROOT}/OSX/SFContext.hpp
|
||||
${SRCROOT}/OSX/SFContext.mm
|
||||
${SRCROOT}/OSX/SFOpenGLView.h
|
||||
${SRCROOT}/OSX/SFOpenGLView.mm
|
||||
${SRCROOT}/OSX/SFWindow.h
|
||||
${SRCROOT}/OSX/SFWindow.m
|
||||
${SRCROOT}/OSX/SFWindowController.h
|
||||
${SRCROOT}/OSX/SFWindowController.mm
|
||||
${SRCROOT}/OSX/VideoModeImpl.cpp
|
||||
${SRCROOT}/OSX/WindowImplCocoa.hpp
|
||||
${SRCROOT}/OSX/WindowImplCocoa.mm
|
||||
${SRCROOT}/OSX/WindowImplDelegateProtocol.h
|
||||
)
|
||||
endif()
|
||||
|
@ -84,8 +86,8 @@ set(WINDOW_EXT_LIBS ${OPENGL_gl_LIBRARY})
|
|||
if(WINDOWS)
|
||||
set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} winmm gdi32)
|
||||
elseif(LINUX)
|
||||
set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} ${X11_X11_LIB} ${X11_Xrandr_LIB})
|
||||
elseif(MACOSX)
|
||||
set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} ${X11_X11_LIB} ${X11_Xrandr_LIB})
|
||||
elseif(MACOSX)
|
||||
set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} "-framework Foundation -framework AppKit")
|
||||
endif()
|
||||
|
||||
|
|
|
@ -54,11 +54,4 @@ void Context::SetActive(bool active)
|
|||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Context::SetReferenceActive()
|
||||
{
|
||||
return priv::GlContext::SetReferenceActive();
|
||||
}
|
||||
|
||||
|
||||
} // namespace sf
|
||||
|
|
|
@ -27,9 +27,13 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/GlContext.hpp>
|
||||
#include <SFML/System/ThreadLocalPtr.hpp>
|
||||
#include <SFML/System/Mutex.hpp>
|
||||
#include <SFML/System/Lock.hpp>
|
||||
#include <SFML/OpenGL.hpp>
|
||||
#include <SFML/Window/glext/glext.h>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
|
||||
|
||||
#if defined(SFML_SYSTEM_WINDOWS)
|
||||
|
@ -55,16 +59,29 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
namespace
|
||||
{
|
||||
// This thread-local variable will hold the "global" context for each thread
|
||||
sf::ThreadLocalPtr<sf::priv::GlContext> threadContext(NULL);
|
||||
// This per-thread variable holds the current context for each thread
|
||||
sf::ThreadLocalPtr<sf::priv::GlContext> currentContext = NULL;
|
||||
|
||||
// Now we create two global contexts.
|
||||
// The first one is the reference context: it will be shared with every other
|
||||
// context, and it can't be activated if we want the sharing operation to always succeed.
|
||||
// That's why we need the second context: this one will be activated and used
|
||||
// in the main thread whenever there's no other context (window) active.
|
||||
ContextType referenceContext(NULL);
|
||||
ContextType defaultContext(&referenceContext);
|
||||
// The hidden, inactive context that will be shared with all other contexts
|
||||
ContextType* sharedContext = NULL;
|
||||
|
||||
// Internal contexts
|
||||
sf::ThreadLocalPtr<sf::priv::GlContext> internalContext = NULL;
|
||||
std::vector<sf::priv::GlContext*> internalContexts;
|
||||
sf::Mutex internalContextsMutex;
|
||||
|
||||
// Retrieve the internal context for the current thread
|
||||
sf::priv::GlContext* GetInternalContext()
|
||||
{
|
||||
if (!internalContext)
|
||||
{
|
||||
internalContext = sf::priv::GlContext::New();
|
||||
sf::Lock lock(internalContextsMutex);
|
||||
internalContexts.push_back(internalContext);
|
||||
}
|
||||
|
||||
return internalContext;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -72,17 +89,58 @@ namespace sf
|
|||
{
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
void GlContext::Initialize()
|
||||
{
|
||||
// Create the shared context
|
||||
sharedContext = new ContextType(NULL);
|
||||
|
||||
// This call makes sure that:
|
||||
// - the shared context is inactive (it must never be)
|
||||
// - another valid context is activated in the current thread
|
||||
sharedContext->SetActive(false);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void GlContext::Cleanup()
|
||||
{
|
||||
// Destroy the shared context
|
||||
delete sharedContext;
|
||||
sharedContext = NULL;
|
||||
|
||||
// Destroy the internal contexts
|
||||
sf::Lock lock(internalContextsMutex);
|
||||
for (std::vector<GlContext*>::iterator it = internalContexts.begin(); it != internalContexts.end(); ++it)
|
||||
delete *it;
|
||||
internalContexts.clear();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void GlContext::EnsureContext()
|
||||
{
|
||||
// If there's no active context on the current thread, activate an internal one
|
||||
if (!currentContext)
|
||||
GetInternalContext()->SetActive(true);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
GlContext* GlContext::New()
|
||||
{
|
||||
return new ContextType(&referenceContext);
|
||||
return new ContextType(sharedContext);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
GlContext* GlContext::New(const WindowImpl* owner, unsigned int bitsPerPixel, const ContextSettings& settings)
|
||||
{
|
||||
ContextType* context = new ContextType(&referenceContext, owner, bitsPerPixel, settings);
|
||||
// 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);
|
||||
|
||||
// Enable antialiasing if needed
|
||||
if (context->GetSettings().AntialiasingLevel > 0)
|
||||
|
@ -95,15 +153,8 @@ GlContext* GlContext::New(const WindowImpl* owner, unsigned int bitsPerPixel, co
|
|||
////////////////////////////////////////////////////////////
|
||||
GlContext::~GlContext()
|
||||
{
|
||||
if (threadContext == this)
|
||||
{
|
||||
threadContext = NULL;
|
||||
}
|
||||
else if (threadContext)
|
||||
{
|
||||
// Don't call this->SetActive(false), it would lead to a pure virtual function call
|
||||
threadContext->SetActive(true);
|
||||
}
|
||||
// Deactivate the context before killing it
|
||||
SetActive(false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -119,42 +170,40 @@ bool GlContext::SetActive(bool active)
|
|||
{
|
||||
if (active)
|
||||
{
|
||||
// Activate the context
|
||||
if (MakeCurrent())
|
||||
if (this != currentContext)
|
||||
{
|
||||
// If this is the first context to be activated on this thread, make
|
||||
// it the reference context for the whole thread.
|
||||
// referenceContext must *not* be the threadContext of the main thread
|
||||
if (!threadContext && (this != &referenceContext))
|
||||
threadContext = this;
|
||||
|
||||
// Activate the context
|
||||
if (MakeCurrent())
|
||||
{
|
||||
// Set it as the new current context for this thread
|
||||
currentContext = this;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// This context is already the active one on this thread, don't do anything
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Deactivate the context
|
||||
if (threadContext && (threadContext != this))
|
||||
if (this == currentContext)
|
||||
{
|
||||
// To deactivate the context, we actually activate another one
|
||||
// so that we make sure that there is always an active context
|
||||
// for subsequent graphics operations
|
||||
return threadContext->SetActive(true);
|
||||
// To deactivate the context, we actually activate another one so that we make
|
||||
// sure that there is always an active context for subsequent graphics operations
|
||||
return GetInternalContext()->SetActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This context is not the active one on this thread, don't do anything
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// If we got there then something failed
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool GlContext::SetReferenceActive()
|
||||
{
|
||||
if (threadContext)
|
||||
return threadContext->SetActive(true);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -47,6 +47,36 @@ class GlContext : NonCopyable
|
|||
{
|
||||
public :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Perform the global initialization
|
||||
///
|
||||
/// This function is called once, before the very first OpenGL
|
||||
/// resource is created. It makes sure that everything is ready
|
||||
/// for contexts to work properly.
|
||||
/// Note: this function doesn't need to be thread-safe, as it
|
||||
/// can be called only once.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static void Initialize();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Perform the global cleanup
|
||||
///
|
||||
/// This function is called after the very last OpenGL resource
|
||||
/// is destroyed. It makes sure that everything that was
|
||||
/// created by Initialize() is properly released.
|
||||
/// Note: this function doesn't need to be thread-safe, as it
|
||||
/// can be called only once.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static void Cleanup();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Ensures that an OpenGL context is active in the current thread
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static void EnsureContext();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Create a new context, not associated to a window
|
||||
///
|
||||
|
@ -129,18 +159,6 @@ public :
|
|||
////////////////////////////////////////////////////////////
|
||||
virtual void EnableVerticalSync(bool enabled) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Make the current thread's reference context active
|
||||
///
|
||||
/// This function is meant to be called internally; it is used
|
||||
/// to deactivate the current context by activating another one
|
||||
/// (so that we still have an active context on the current thread).
|
||||
///
|
||||
/// \return True if operation was successful, false otherwise
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool SetReferenceActive();
|
||||
|
||||
protected :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
|
89
src/SFML/Window/GlResource.cpp
Normal file
89
src/SFML/Window/GlResource.cpp
Normal file
|
@ -0,0 +1,89 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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/Window/GlResource.hpp>
|
||||
#include <SFML/Window/GlContext.hpp>
|
||||
#include <SFML/System/Mutex.hpp>
|
||||
#include <SFML/System/Lock.hpp>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Private data
|
||||
////////////////////////////////////////////////////////////
|
||||
namespace
|
||||
{
|
||||
// OpenGL resources counter and its mutex
|
||||
unsigned long count = 0;
|
||||
bool initialized = false;
|
||||
sf::Mutex mutex;
|
||||
}
|
||||
|
||||
|
||||
namespace sf
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
GlResource::GlResource()
|
||||
{
|
||||
{
|
||||
// Protect from concurrent access
|
||||
Lock lock(mutex);
|
||||
|
||||
// If this is the very first resource, trigger the global context initialization
|
||||
if (count == 0)
|
||||
priv::GlContext::Initialize();
|
||||
|
||||
// Increment the resources counter
|
||||
count++;
|
||||
}
|
||||
|
||||
// Now make sure that there is an active OpenGL context in the current thread
|
||||
priv::GlContext::EnsureContext();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
GlResource::~GlResource()
|
||||
{
|
||||
// Protect from concurrent access
|
||||
Lock lock(mutex);
|
||||
|
||||
// Decrement the resources counter
|
||||
count--;
|
||||
|
||||
// If there's no more resource alive, we can trigger the global context cleanup
|
||||
if (count == 0)
|
||||
priv::GlContext::Cleanup();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void GlResource::EnsureGlContext()
|
||||
{
|
||||
priv::GlContext::EnsureContext();
|
||||
}
|
||||
|
||||
} // namespace sf
|
|
@ -116,17 +116,7 @@ GlxContext::~GlxContext()
|
|||
////////////////////////////////////////////////////////////
|
||||
bool GlxContext::MakeCurrent()
|
||||
{
|
||||
if (myContext)
|
||||
{
|
||||
if (glXGetCurrentContext() != myContext)
|
||||
return glXMakeCurrent(myDisplay, myWindow, myContext) != 0;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return myContext && glXMakeCurrent(myDisplay, myWindow, myContext);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -107,17 +107,7 @@ WglContext::~WglContext()
|
|||
////////////////////////////////////////////////////////////
|
||||
bool WglContext::MakeCurrent()
|
||||
{
|
||||
if (myDeviceContext && myContext)
|
||||
{
|
||||
if (wglGetCurrentContext() != myContext)
|
||||
return wglMakeCurrent(myDeviceContext, myContext) != 0;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return myDeviceContext && myContext && wglMakeCurrent(myDeviceContext, myContext);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue