mirror of
https://github.com/SFML/SFML.git
synced 2024-11-24 20:31:05 +08:00
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
@ -130,16 +130,16 @@ int main()
|
||||
ShaderSelector globalShader(shaders, "nothing");
|
||||
|
||||
// Do specific initializations
|
||||
shaders["nothing"].SetTexture("texture", sf::Shader::CurrentTexture);
|
||||
shaders["blur"].SetTexture("texture", sf::Shader::CurrentTexture);
|
||||
shaders["nothing"].SetCurrentTexture("texture");
|
||||
shaders["blur"].SetCurrentTexture("texture");
|
||||
shaders["blur"].SetParameter("offset", 0.f);
|
||||
shaders["colorize"].SetTexture("texture", sf::Shader::CurrentTexture);
|
||||
shaders["colorize"].SetCurrentTexture("texture");
|
||||
shaders["colorize"].SetParameter("color", 1.f, 1.f, 1.f);
|
||||
shaders["edge"].SetTexture("texture", sf::Shader::CurrentTexture);
|
||||
shaders["fisheye"].SetTexture("texture", sf::Shader::CurrentTexture);
|
||||
shaders["wave"].SetTexture("texture", sf::Shader::CurrentTexture);
|
||||
shaders["edge"].SetCurrentTexture("texture");
|
||||
shaders["fisheye"].SetCurrentTexture("texture");
|
||||
shaders["wave"].SetCurrentTexture("texture");
|
||||
shaders["wave"].SetTexture("wave", waveImage);
|
||||
shaders["pixelate"].SetTexture("texture", sf::Shader::CurrentTexture);
|
||||
shaders["pixelate"].SetCurrentTexture("texture");
|
||||
|
||||
// Define a string for displaying the description of the current shader
|
||||
sf::Text shaderStr;
|
||||
|
@ -29,6 +29,7 @@
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/System/Resource.hpp>
|
||||
#include <SFML/Window/GlResource.hpp>
|
||||
#include <SFML/Graphics/Color.hpp>
|
||||
#include <SFML/Graphics/Rect.hpp>
|
||||
#include <string>
|
||||
@ -45,7 +46,7 @@ class RenderWindow;
|
||||
/// \brief Class for loading, manipulating and saving images
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class SFML_API Image : public Resource<Image>
|
||||
class SFML_API Image : public Resource<Image>, GlResource
|
||||
{
|
||||
public :
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Config.hpp>
|
||||
#include <SFML/System/NonCopyable.hpp>
|
||||
#include <SFML/Window/GlResource.hpp>
|
||||
#include <SFML/Graphics/Color.hpp>
|
||||
#include <SFML/Graphics/Drawable.hpp>
|
||||
#include <SFML/Graphics/Matrix3.hpp>
|
||||
@ -44,7 +45,7 @@ class Shader;
|
||||
/// \brief Handles the low-level rendering (states and geometry)
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class SFML_API Renderer : NonCopyable
|
||||
class SFML_API Renderer : GlResource, NonCopyable
|
||||
{
|
||||
public :
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Config.hpp>
|
||||
#include <SFML/Graphics/Image.hpp>
|
||||
#include <SFML/Window/GlResource.hpp>
|
||||
#include <SFML/System/Vector2.hpp>
|
||||
#include <SFML/System/Vector3.hpp>
|
||||
#include <map>
|
||||
@ -44,7 +45,7 @@ class Renderer;
|
||||
/// \brief Pixel/fragment shader class
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class SFML_API Shader
|
||||
class SFML_API Shader : GlResource
|
||||
{
|
||||
public :
|
||||
|
||||
@ -120,7 +121,7 @@ public :
|
||||
/// \param name Name of the parameter in the shader
|
||||
/// \param x Value to assign
|
||||
///
|
||||
/// \see SetTexture
|
||||
/// \see SetTexture, SetCurrentTexture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void SetParameter(const std::string& name, float x);
|
||||
@ -141,7 +142,7 @@ public :
|
||||
/// \param x First component of the value to assign
|
||||
/// \param y Second component of the value to assign
|
||||
///
|
||||
/// \see SetTexture
|
||||
/// \see SetTexture, SetCurrentTexture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void SetParameter(const std::string& name, float x, float y);
|
||||
@ -163,7 +164,7 @@ public :
|
||||
/// \param y Second component of the value to assign
|
||||
/// \param z Third component of the value to assign
|
||||
///
|
||||
/// \see SetTexture
|
||||
/// \see SetTexture, SetCurrentTexture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void SetParameter(const std::string& name, float x, float y, float z);
|
||||
@ -186,7 +187,7 @@ public :
|
||||
/// \param z Third component of the value to assign
|
||||
/// \param w Fourth component of the value to assign
|
||||
///
|
||||
/// \see SetTexture
|
||||
/// \see SetTexture, SetCurrentTexture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void SetParameter(const std::string& name, float x, float y, float z, float w);
|
||||
@ -206,7 +207,7 @@ public :
|
||||
/// \param name Name of the parameter in the shader
|
||||
/// \param vector Vector to assign
|
||||
///
|
||||
/// \see SetTexture
|
||||
/// \see SetTexture, SetCurrentTexture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void SetParameter(const std::string& name, const Vector2f& vector);
|
||||
@ -226,7 +227,7 @@ public :
|
||||
/// \param name Name of the parameter in the shader
|
||||
/// \param vector Vector to assign
|
||||
///
|
||||
/// \see SetTexture
|
||||
/// \see SetTexture, SetCurrentTexture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void SetParameter(const std::string& name, const Vector3f& vector);
|
||||
@ -235,19 +236,18 @@ public :
|
||||
/// \brief Change a texture parameter of the shader
|
||||
///
|
||||
/// \a name is the name of the texture to change in the shader.
|
||||
/// To tell the shader to use the current texture of the object being
|
||||
/// drawn, pass Shader::CurrentTexture.
|
||||
/// This function maps an external image to the texture variable;
|
||||
/// to use the current texture of the object being drawn, use
|
||||
/// SetCurrentTexture instead.
|
||||
/// Example:
|
||||
/// \code
|
||||
/// // These are the variables in the pixel shader
|
||||
/// uniform sampler2D current;
|
||||
/// uniform sampler2D other;
|
||||
/// uniform sampler2D texture;
|
||||
/// \endcode
|
||||
/// \code
|
||||
/// sf::Image image;
|
||||
/// ...
|
||||
/// shader.SetParameter("current", sf::Shader::CurrentTexture);
|
||||
/// shader.SetParameter("other", image);
|
||||
/// shader.SetTexture("texture", image);
|
||||
/// \endcode
|
||||
/// It is important to note that \a texture must remain alive as long
|
||||
/// as the shader uses it, no copy is made internally.
|
||||
@ -255,11 +255,32 @@ public :
|
||||
/// \param name Name of the texture in the shader
|
||||
/// \param texture Image to assign
|
||||
///
|
||||
/// \see SetParameter
|
||||
/// \see SetParameter, SetCurrentTexture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void SetTexture(const std::string& name, const Image& texture);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Set the current object texture in the shader
|
||||
///
|
||||
/// This function maps a shader texture variable to the
|
||||
/// image of the object being drawn.
|
||||
/// Example:
|
||||
/// \code
|
||||
/// // This is the variable in the pixel shader
|
||||
/// uniform sampler2D current;
|
||||
/// \endcode
|
||||
/// \code
|
||||
/// shader.SetCurrentTexture("current");
|
||||
/// \endcode
|
||||
///
|
||||
/// \param name Name of the texture in the shader
|
||||
///
|
||||
/// \see SetParameter, SetTexture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void SetCurrentTexture(const std::string& name);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Bind the shader for rendering (activate it)
|
||||
///
|
||||
@ -312,11 +333,6 @@ public :
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool IsAvailable();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Static member data
|
||||
////////////////////////////////////////////////////////////
|
||||
static const Image CurrentTexture; ///< Special image representing the texture used by the object being drawn
|
||||
|
||||
private :
|
||||
|
||||
friend class Renderer;
|
||||
@ -394,12 +410,12 @@ private :
|
||||
/// \code
|
||||
/// shader.SetParameter("offset", 2.f);
|
||||
/// shader.SetParameter("color", 0.5f, 0.8f, 0.3f);
|
||||
/// shader.SetTexture("image", image); // image is a sf::Image
|
||||
/// shader.SetTexture("current", sf::Shader::CurrentTexture);
|
||||
/// shader.SetTexture("overlay", image); // image is a sf::Image
|
||||
/// shader.SetCurrentTexture("texture");
|
||||
/// \endcode
|
||||
///
|
||||
/// Shader::CurrentTexture is a special value that represents
|
||||
/// the texture that the object being drawn is using.
|
||||
/// Shader::SetCurrentTexture maps the given texture variable
|
||||
/// to the current texture of the object being drawn.
|
||||
///
|
||||
/// To apply a shader to a drawable, you must pass it as an
|
||||
/// additional parameter to the Draw function:
|
||||
|
@ -29,6 +29,7 @@
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Config.hpp>
|
||||
#include <SFML/Window/GlResource.hpp>
|
||||
#include <SFML/System/NonCopyable.hpp>
|
||||
|
||||
|
||||
@ -43,7 +44,7 @@ namespace priv
|
||||
/// \brief Class holding a valid drawing context
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class SFML_API Context : NonCopyable
|
||||
class SFML_API Context : GlResource, NonCopyable
|
||||
{
|
||||
public :
|
||||
|
||||
@ -71,18 +72,6 @@ public :
|
||||
////////////////////////////////////////////////////////////
|
||||
void SetActive(bool active);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Make the current thread's reference context active
|
||||
///
|
||||
/// This function is meant to be called internally; it is used
|
||||
/// to deactivate the current context by activating another one
|
||||
/// (so that we still have an active context on the current thread).
|
||||
///
|
||||
/// \return True if operation was successful, false otherwise
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool SetReferenceActive();
|
||||
|
||||
private :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
72
include/SFML/Window/GlResource.hpp
Normal file
72
include/SFML/Window/GlResource.hpp
Normal file
@ -0,0 +1,72 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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_GLRESOURCE_HPP
|
||||
#define SFML_GLRESOURCE_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Config.hpp>
|
||||
|
||||
|
||||
namespace sf
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Base class for classes that require an OpenGL context
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class SFML_API GlResource
|
||||
{
|
||||
protected :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Default constructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
GlResource();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Destructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
~GlResource();
|
||||
|
||||
static void EnsureGlContext();
|
||||
};
|
||||
|
||||
} // namespace sf
|
||||
|
||||
|
||||
#endif // SFML_GLRESOURCE_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \class sf::GlResource
|
||||
/// \ingroup window
|
||||
///
|
||||
/// This class is for internal use only, it must be the base
|
||||
/// of every class that requires a valid OpenGL context in
|
||||
/// order to work.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
@ -33,6 +33,7 @@
|
||||
#include <SFML/Window/VideoMode.hpp>
|
||||
#include <SFML/Window/WindowHandle.hpp>
|
||||
#include <SFML/Window/WindowStyle.hpp>
|
||||
#include <SFML/Window/GlResource.hpp>
|
||||
#include <SFML/System/Clock.hpp>
|
||||
#include <SFML/System/NonCopyable.hpp>
|
||||
#include <string>
|
||||
@ -52,7 +53,7 @@ class Event;
|
||||
/// \brief Window that serves as a target for OpenGL rendering
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class SFML_API Window : NonCopyable
|
||||
class SFML_API Window : GlResource, NonCopyable
|
||||
{
|
||||
public :
|
||||
|
||||
|
@ -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…
Reference in New Issue
Block a user