diff --git a/CSFML/src/SFML/Window/Context.cpp b/CSFML/src/SFML/Window/Context.cpp index 7b0ac35d..2f2e1003 100644 --- a/CSFML/src/SFML/Window/Context.cpp +++ b/CSFML/src/SFML/Window/Context.cpp @@ -32,11 +32,7 @@ struct sfContext { - sfContext() : This(sf::Context::New()) {} - - ~sfContext() {delete This;} - - sf::Context* This; + sf::Context This; }; @@ -63,5 +59,5 @@ void sfContext_Destroy(sfContext* Context) //////////////////////////////////////////////////////////// void sfContext_SetActive(sfContext* Context, sfBool Active) { - CSFML_CALL_PTR(Context, SetActive(Active == sfTrue)) + CSFML_CALL(Context, SetActive(Active == sfTrue)) } diff --git a/build/codeblocks/SFML.workspace b/build/codeblocks/SFML.workspace index a55cc15e..56e3f261 100644 --- a/build/codeblocks/SFML.workspace +++ b/build/codeblocks/SFML.workspace @@ -1,11 +1,11 @@ - + - + diff --git a/build/codeblocks/sfml-graphics.cbp b/build/codeblocks/sfml-graphics.cbp index a6a61142..5230223d 100644 --- a/build/codeblocks/sfml-graphics.cbp +++ b/build/codeblocks/sfml-graphics.cbp @@ -138,14 +138,14 @@ + + - - diff --git a/build/codeblocks/sfml-system.cbp b/build/codeblocks/sfml-system.cbp index 6ae9ecc0..4a1bd373 100644 --- a/build/codeblocks/sfml-system.cbp +++ b/build/codeblocks/sfml-system.cbp @@ -99,6 +99,9 @@ + + + @@ -112,6 +115,7 @@ + @@ -119,6 +123,8 @@ + + diff --git a/build/codeblocks/sfml-window.cbp b/build/codeblocks/sfml-window.cbp index 7a1b38a7..7ea8c3ab 100644 --- a/build/codeblocks/sfml-window.cbp +++ b/build/codeblocks/sfml-window.cbp @@ -119,6 +119,8 @@ + + diff --git a/build/vc2005/sfml-graphics.vcproj b/build/vc2005/sfml-graphics.vcproj index 3b34601e..f2fe6b0a 100644 --- a/build/vc2005/sfml-graphics.vcproj +++ b/build/vc2005/sfml-graphics.vcproj @@ -3314,18 +3314,18 @@ RelativePath="..\..\src\SFML\Graphics\FontLoader.hpp" > + + + + - - - - diff --git a/build/vc2005/sfml-system.vcproj b/build/vc2005/sfml-system.vcproj index d357c97b..52490548 100644 --- a/build/vc2005/sfml-system.vcproj +++ b/build/vc2005/sfml-system.vcproj @@ -365,6 +365,14 @@ RelativePath="..\..\src\SFML\System\Win32\ThreadImpl.hpp" > + + + + + + + + + + + + diff --git a/build/vc2005/sfml-window.vcproj b/build/vc2005/sfml-window.vcproj index d53068fb..a3187c5d 100644 --- a/build/vc2005/sfml-window.vcproj +++ b/build/vc2005/sfml-window.vcproj @@ -456,6 +456,14 @@ RelativePath="..\..\include\SFML\Window\Context.hpp" > + + + + diff --git a/build/vc2008/sfml-graphics.vcproj b/build/vc2008/sfml-graphics.vcproj index 24a62a30..329cdb7e 100644 --- a/build/vc2008/sfml-graphics.vcproj +++ b/build/vc2008/sfml-graphics.vcproj @@ -3308,18 +3308,18 @@ RelativePath="..\..\src\SFML\Graphics\FontLoader.hpp" > + + + + - - - - diff --git a/build/vc2008/sfml-system.vcproj b/build/vc2008/sfml-system.vcproj index 00cf086c..0e4c066b 100644 --- a/build/vc2008/sfml-system.vcproj +++ b/build/vc2008/sfml-system.vcproj @@ -358,6 +358,14 @@ RelativePath="..\..\src\SFML\System\Win32\ThreadImpl.hpp" > + + + + + + + + + + + + diff --git a/build/vc2008/sfml-window.vcproj b/build/vc2008/sfml-window.vcproj index 564e3bb6..e393f9f4 100644 --- a/build/vc2008/sfml-window.vcproj +++ b/build/vc2008/sfml-window.vcproj @@ -415,6 +415,14 @@ RelativePath="..\..\include\SFML\Window\Context.hpp" > + + + + diff --git a/dotnet/extlibs/csfml-audio.dll b/dotnet/extlibs/csfml-audio.dll index 9627ee95..e5bd1ddc 100644 Binary files a/dotnet/extlibs/csfml-audio.dll and b/dotnet/extlibs/csfml-audio.dll differ diff --git a/dotnet/extlibs/csfml-graphics.dll b/dotnet/extlibs/csfml-graphics.dll index 846ebdc0..586ef315 100644 Binary files a/dotnet/extlibs/csfml-graphics.dll and b/dotnet/extlibs/csfml-graphics.dll differ diff --git a/dotnet/extlibs/csfml-window.dll b/dotnet/extlibs/csfml-window.dll index 52dad2d2..31cdd955 100644 Binary files a/dotnet/extlibs/csfml-window.dll and b/dotnet/extlibs/csfml-window.dll differ diff --git a/dotnet/src/Graphics/Image.cs b/dotnet/src/Graphics/Image.cs index be66c282..46336194 100644 --- a/dotnet/src/Graphics/Image.cs +++ b/dotnet/src/Graphics/Image.cs @@ -70,7 +70,7 @@ namespace SFML { if (This == IntPtr.Zero) throw new LoadingFailedException("image", filename); - } + } //////////////////////////////////////////////////////////// /// diff --git a/include/SFML/System.hpp b/include/SFML/System.hpp index 63502102..63661f66 100644 --- a/include/SFML/System.hpp +++ b/include/SFML/System.hpp @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/include/SFML/System/ThreadLocal.hpp b/include/SFML/System/ThreadLocal.hpp new file mode 100644 index 00000000..37b95033 --- /dev/null +++ b/include/SFML/System/ThreadLocal.hpp @@ -0,0 +1,95 @@ +//////////////////////////////////////////////////////////// +// +// 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_THREADLOCAL_HPP +#define SFML_THREADLOCAL_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include + + +namespace sf +{ +namespace priv +{ + class ThreadLocalImpl; +} + +//////////////////////////////////////////////////////////// +/// Wrapper to handle variables that are local to threads. +/// This means that the same ThreadLocalStorage variable will +/// hold a different value for each different thread. +/// For a more strongly-typed interface, use the ThreadLocal +/// template class. +//////////////////////////////////////////////////////////// +class SFML_API ThreadLocal : NonCopyable +{ +public : + + //////////////////////////////////////////////////////////// + /// Default constructor + /// + /// \param Value : Optional value to initalize the variable (NULL by default) + /// + //////////////////////////////////////////////////////////// + ThreadLocal(void* Value = NULL); + + //////////////////////////////////////////////////////////// + /// Destructor + /// + //////////////////////////////////////////////////////////// + ~ThreadLocal(); + + //////////////////////////////////////////////////////////// + /// Set the thread-specific value of the variable + /// + /// \param Value : Value of the variable for this thread + /// + //////////////////////////////////////////////////////////// + void SetValue(void* Value); + + //////////////////////////////////////////////////////////// + /// Retrieve the thread-specific value of the variable + /// + /// \return Value of the variable for this thread + /// + //////////////////////////////////////////////////////////// + void* GetValue() const; + +private : + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + priv::ThreadLocalImpl* myImpl; ///< Pointer to the OS specific implementation +}; + +} // namespace sf + + +#endif // SFML_THREADLOCAL_HPP diff --git a/include/SFML/System/ThreadLocalPtr.hpp b/include/SFML/System/ThreadLocalPtr.hpp new file mode 100644 index 00000000..ffc75937 --- /dev/null +++ b/include/SFML/System/ThreadLocalPtr.hpp @@ -0,0 +1,102 @@ +//////////////////////////////////////////////////////////// +// +// 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_THREADLOCALPTR_HPP +#define SFML_THREADLOCALPTR_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// Type-safe wrapper for thread local pointer variables +//////////////////////////////////////////////////////////// +template +class ThreadLocalPtr : private ThreadLocal +{ +public : + + //////////////////////////////////////////////////////////// + /// Default constructor + /// + /// \param Value : Optional value to initalize the variable (NULL by default) + /// + //////////////////////////////////////////////////////////// + ThreadLocalPtr(T* Value = NULL); + + //////////////////////////////////////////////////////////// + /// Operator * overload to return a reference to the variable + /// + /// \return Reference to the thread-local value of the variable + /// + //////////////////////////////////////////////////////////// + T& operator *() const; + + //////////////////////////////////////////////////////////// + /// Operator -> overload to return a pointer to the variable + /// + /// \return Pointer to the thread-local value of the variable + /// + //////////////////////////////////////////////////////////// + T* operator ->() const; + + //////////////////////////////////////////////////////////// + /// Implicit cast operator to T* + /// + /// \return Value of the pointer for this thread + /// + //////////////////////////////////////////////////////////// + operator T*() const; + + //////////////////////////////////////////////////////////// + /// Assignment operator + /// + /// \param Value : New pointer value to assign for this thread + /// + /// \return Reference to this + /// + //////////////////////////////////////////////////////////// + ThreadLocalPtr& operator =(T* Value); + + //////////////////////////////////////////////////////////// + /// Assignment operator + /// + /// \param Other : Other thread-local pointer value to assign + /// + /// \return Reference to this + /// + //////////////////////////////////////////////////////////// + ThreadLocalPtr& operator =(const ThreadLocalPtr& Other); +}; + +} // namespace sf + +#include + + +#endif // SFML_THREADLOCALPTR_HPP diff --git a/include/SFML/System/ThreadLocalPtr.inl b/include/SFML/System/ThreadLocalPtr.inl new file mode 100644 index 00000000..c4f8719d --- /dev/null +++ b/include/SFML/System/ThreadLocalPtr.inl @@ -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. +// +//////////////////////////////////////////////////////////// + + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// Default constructor +//////////////////////////////////////////////////////////// +template +ThreadLocalPtr::ThreadLocalPtr(T* Value) : +ThreadLocal(Value) +{ +} + + +//////////////////////////////////////////////////////////// +/// Operator * overload to return a reference to the variable +//////////////////////////////////////////////////////////// +template +T& ThreadLocalPtr::operator *() const +{ + return *static_cast(GetValue()); +} + + +//////////////////////////////////////////////////////////// +/// Operator -> overload to return a pointer to the variable +//////////////////////////////////////////////////////////// +template +T* ThreadLocalPtr::operator ->() const +{ + return static_cast(GetValue()); +} + + +//////////////////////////////////////////////////////////// +/// Implicit cast operator to T* +//////////////////////////////////////////////////////////// +template +ThreadLocalPtr::operator T*() const +{ + return static_cast(GetValue()); +} + + +//////////////////////////////////////////////////////////// +/// Assignment operator +//////////////////////////////////////////////////////////// +template +ThreadLocalPtr& ThreadLocalPtr::operator =(T* Value) +{ + SetValue(Value); + return *this; +} + + +//////////////////////////////////////////////////////////// +/// Assignment operator +//////////////////////////////////////////////////////////// +template +ThreadLocalPtr& ThreadLocalPtr::operator =(const ThreadLocalPtr& Other) +{ + SetValue(Other.GetValue()); + return *this; +} + +} // namespace sf diff --git a/include/SFML/Window/Context.hpp b/include/SFML/Window/Context.hpp index 06b29eef..aeeaa49e 100644 --- a/include/SFML/Window/Context.hpp +++ b/include/SFML/Window/Context.hpp @@ -29,7 +29,6 @@ // Headers //////////////////////////////////////////////////////////// #include -#include #include @@ -37,132 +36,70 @@ namespace sf { namespace priv { -class WindowImpl; + class ContextGL; } //////////////////////////////////////////////////////////// -/// Abstract class representing an OpenGL context +/// Class holding a valid drawing context +/// +/// If you need to make OpenGL / graphics calls without +/// having an active window (like in a thread), you can use +/// an instance of this class to get a valid context. +/// +/// Having a valid context is necessary for *every* OpenGL call, +/// and for most of the classes from the Graphics package. +/// +/// Note that a context is only active in its current thread, +/// if you create a new thread it will have no valid context +/// by default. +/// +/// \code +/// void ThreadedFunc(void*) +/// { +/// sf::Context Ctx; +/// // from now on, you have a valid context +/// +/// // you can make OpenGL calls +/// glClear(GL_DEPTH_BUFFER_BIT); +/// +/// // as well as using objects from the graphics package +/// sf::Image Img; +/// Img.LoadFromFile("image.png"); +/// } +/// // the context is automatically deactivated and destroyed +/// // by the sf::Context destructor +/// \endcode //////////////////////////////////////////////////////////// class SFML_API Context : NonCopyable { public : //////////////////////////////////////////////////////////// - /// Create a new context, not associated to a window - /// - /// \return Pointer to the created context - /// - //////////////////////////////////////////////////////////// - static Context* New(); - - //////////////////////////////////////////////////////////// - /// Create a new context attached to a window - /// - /// \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 - /// - //////////////////////////////////////////////////////////// - static Context* New(const priv::WindowImpl* Owner, unsigned int BitsPerPixel, const ContextSettings& Settings); - - //////////////////////////////////////////////////////////// - /// Check if a context is active on the current thread - /// - /// \return True if there's an active context, false otherwise - /// - //////////////////////////////////////////////////////////// - static bool IsContextActive(); - - //////////////////////////////////////////////////////////// - /// Return the default context - /// - /// \return Reference to the default context - /// - //////////////////////////////////////////////////////////// - static Context& GetDefault(); - -public : - - //////////////////////////////////////////////////////////// - /// Virtual destructor - /// - //////////////////////////////////////////////////////////// - virtual ~Context(); - - //////////////////////////////////////////////////////////// - /// Get the settings of the context - /// - /// \return Structure containing the settings - /// - //////////////////////////////////////////////////////////// - const ContextSettings& GetSettings() const; - - //////////////////////////////////////////////////////////// - /// Activate or deactivate the context as the current target - /// for rendering - /// - /// \param Active : True to activate, false to deactivate - /// - /// \return True if operation was successful, false otherwise - /// - //////////////////////////////////////////////////////////// - bool SetActive(bool Active); - - //////////////////////////////////////////////////////////// - /// Display the contents of the context - /// - //////////////////////////////////////////////////////////// - virtual void Display() = 0; - - //////////////////////////////////////////////////////////// - /// Enable / disable vertical synchronization - /// - /// \param Enabled : True to enable v-sync, false to deactivate - /// - //////////////////////////////////////////////////////////// - virtual void UseVerticalSync(bool Enabled) = 0; - -protected : - - //////////////////////////////////////////////////////////// - /// Default constructor + /// Default constructor -- creates and activates the context /// //////////////////////////////////////////////////////////// Context(); //////////////////////////////////////////////////////////// - /// Make this context the current one - /// - /// \param Active : True to activate, false to deactivate - /// - /// \return True on success, false if any error happened + /// Destructor -- deactivates and destroys the context /// //////////////////////////////////////////////////////////// - virtual bool MakeCurrent(bool Active) = 0; + ~Context(); //////////////////////////////////////////////////////////// - /// Evaluate a pixel format configuration. - /// This functions can be used by implementations that have - /// several valid formats and want to get the best one + /// Activate or deactivate explicitely the context /// - /// \param BitsPerPixel : Requested pixel depth (bits per pixel) - /// \param Settings : Requested additionnal settings - /// \param ColorBits : Color bits of the configuration to evaluate - /// \param DepthBits : Depth bits of the configuration to evaluate - /// \param StencilBits : Stencil bits of the configuration to evaluate - /// \param Antialiasing : Antialiasing level of the configuration to evaluate - /// - /// \return Score of the configuration : the lower the better + /// \param Active True to activate, false to deactivate /// //////////////////////////////////////////////////////////// - static int EvaluateFormat(unsigned int BitsPerPixel, const ContextSettings& Settings, int ColorBits, int DepthBits, int StencilBits, int Antialiasing); + void SetActive(bool Active); + +private : //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - ContextSettings mySettings; ///< Creation settings of the context + priv::ContextGL* myContext; ///< Internal OpenGL context }; } // namespace sf diff --git a/include/SFML/Window/Window.hpp b/include/SFML/Window/Window.hpp index 797c15d3..ef34a445 100644 --- a/include/SFML/Window/Window.hpp +++ b/include/SFML/Window/Window.hpp @@ -46,10 +46,9 @@ namespace sf namespace priv { class WindowImpl; + class ContextGL; } -class Context; - //////////////////////////////////////////////////////////// /// Window is a rendering window ; it can create a new window /// or connect to an existing one @@ -309,7 +308,7 @@ private : // Member data //////////////////////////////////////////////////////////// priv::WindowImpl* myWindow; ///< Platform-specific implementation of the window - Context* myContext; ///< Platform-specific implementation of the OpenGL context + priv::ContextGL* myContext; ///< Platform-specific implementation of the OpenGL context std::queue myEvents; ///< Queue of received events Input myInput; ///< Input manager connected to window Clock myClock; ///< Clock for measuring the elapsed time between frames diff --git a/src/SFML/Graphics/Drawable.cpp b/src/SFML/Graphics/Drawable.cpp index 7ff5d09a..98df0369 100644 --- a/src/SFML/Graphics/Drawable.cpp +++ b/src/SFML/Graphics/Drawable.cpp @@ -26,7 +26,7 @@ // Headers //////////////////////////////////////////////////////////// #include -#include +#include #include #include diff --git a/src/SFML/Graphics/FontLoader.cpp b/src/SFML/Graphics/FontLoader.cpp index 922cac98..cf334567 100644 --- a/src/SFML/Graphics/FontLoader.cpp +++ b/src/SFML/Graphics/FontLoader.cpp @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include FT_GLYPH_H #include #include @@ -163,9 +163,6 @@ bool FontLoader::LoadFontFromMemory(const char* Data, std::size_t SizeInBytes, u //////////////////////////////////////////////////////////// FT_Error FontLoader::CreateBitmapFont(FT_Face FontFace, unsigned int CharSize, const Unicode::UTF32String& Charset, Font& LoadedFont) { - // Make sure we have a valid context - priv::GraphicsContext Ctx; - // Let's find how many characters to put in each row to make them fit into a squared texture GLint MaxSize; GLCheck(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &MaxSize)); diff --git a/src/SFML/Graphics/GraphicsContext.hpp b/src/SFML/Graphics/GLCheck.cpp similarity index 63% rename from src/SFML/Graphics/GraphicsContext.hpp rename to src/SFML/Graphics/GLCheck.cpp index 2fa77a3c..b626b3d4 100644 --- a/src/SFML/Graphics/GraphicsContext.hpp +++ b/src/SFML/Graphics/GLCheck.cpp @@ -22,84 +22,19 @@ // //////////////////////////////////////////////////////////// -#ifndef SFML_GRAPHICSCONTEXT_HPP -#define SFML_GRAPHICSCONTEXT_HPP - //////////////////////////////////////////////////////////// // Headers //////////////////////////////////////////////////////////// -#include -#include -#include +#include #include -#include namespace sf { -class Context; - -namespace priv -{ -//////////////////////////////////////////////////////////// -/// RAII class ensuring a valid shared OpenGL context is bound -/// to the current thread for all the lifetime of the instance. -/// It also ensures all third party libraries (like GLEW) -/// are properly initialized -/// This class is for internal use only, it is required -/// to solve tricky problems involving multi-threading -//////////////////////////////////////////////////////////// -class GraphicsContext : NonCopyable -{ -public : - - //////////////////////////////////////////////////////////// - /// Default constructor, activate the global context - /// if no other context is bound to the current thread - /// - //////////////////////////////////////////////////////////// - GraphicsContext(); - - //////////////////////////////////////////////////////////// - /// Destructor, deactivate the global context - /// if no other context was previously bound to the current thread - /// - //////////////////////////////////////////////////////////// - ~GraphicsContext(); - -private : - - //////////////////////////////////////////////////////////// - // Member data - //////////////////////////////////////////////////////////// - bool myActivated; ///< Keep track of the activation state of the global context -}; - -} // namespace priv - - -//////////////////////////////////////////////////////////// -/// Let's define a macro to quickly check every OpenGL -/// API calls -//////////////////////////////////////////////////////////// -#ifdef SFML_DEBUG - - // In debug mode, perform a test on every OpenGL call - #define GLCheck(Func) ((Func), GLCheckError(__FILE__, __LINE__)) - -#else - - // Else, we don't add any overhead - #define GLCheck(Func) (Func) - -#endif - - //////////////////////////////////////////////////////////// /// Check the last OpenGL error -/// //////////////////////////////////////////////////////////// -inline void GLCheckError(const std::string& File, unsigned int Line) +void GLCheckError(const std::string& File, unsigned int Line) { // Get the last error GLenum ErrorCode = glGetError(); @@ -170,7 +105,18 @@ inline void GLCheckError(const std::string& File, unsigned int Line) } } + +//////////////////////////////////////////////////////////// +/// Make sure that GLEW is initialized +//////////////////////////////////////////////////////////// +void EnsureGlewInit() +{ + static bool Initialized = false; + if (!Initialized) + { + glewInit(); + Initialized = true; + } +} + } // namespace sf - - -#endif // SFML_GRAPHICSCONTEXT_HPP diff --git a/src/SFML/Graphics/GLCheck.hpp b/src/SFML/Graphics/GLCheck.hpp new file mode 100644 index 00000000..fff945bf --- /dev/null +++ b/src/SFML/Graphics/GLCheck.hpp @@ -0,0 +1,73 @@ +//////////////////////////////////////////////////////////// +// +// 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_GLCHECK_HPP +#define SFML_GLCHECK_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include + + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// Let's define a macro to quickly check every OpenGL +/// API calls +//////////////////////////////////////////////////////////// +#ifdef SFML_DEBUG + + // In debug mode, perform a test on every OpenGL call + #define GLCheck(Func) ((Func), GLCheckError(__FILE__, __LINE__)) + +#else + + // Else, we don't add any overhead + #define GLCheck(Func) (Func) + +#endif + + +//////////////////////////////////////////////////////////// +/// Check the last OpenGL error +/// +/// \param File Source file where the call is located +/// \param Line Line number of the source file where the call is located +/// +//////////////////////////////////////////////////////////// +void GLCheckError(const std::string& File, unsigned int Line); + +//////////////////////////////////////////////////////////// +/// Make sure that GLEW is initialized +/// +//////////////////////////////////////////////////////////// +void EnsureGlewInit(); + +} // namespace sf + + +#endif // SFML_GLCHECK_HPP diff --git a/src/SFML/Graphics/Image.cpp b/src/SFML/Graphics/Image.cpp index f90673cd..a3f9e2c2 100644 --- a/src/SFML/Graphics/Image.cpp +++ b/src/SFML/Graphics/Image.cpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include @@ -495,9 +495,6 @@ void Image::SetSmooth(bool Smooth) if (myTexture) { - // Make sure we have a valid context - priv::GraphicsContext Ctx; - GLint PreviousTexture; GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &PreviousTexture)); @@ -569,8 +566,8 @@ FloatRect Image::GetTexCoords(const IntRect& Rect, bool Adjust) const //////////////////////////////////////////////////////////// unsigned int Image::GetValidTextureSize(unsigned int Size) { - // Make sure we have a valid context - priv::GraphicsContext Ctx; + // Make sure that GLEW is initialized + EnsureGlewInit(); if (glewIsSupported("GL_ARB_texture_non_power_of_two") != 0) { @@ -619,9 +616,6 @@ bool Image::CreateTexture() if (!myWidth || !myHeight) return false; - // Make sure we have a valid context - priv::GraphicsContext Ctx; - // Adjust internal texture dimensions depending on NPOT textures support unsigned int TextureWidth = GetValidTextureSize(myWidth); unsigned int TextureHeight = GetValidTextureSize(myHeight); @@ -772,9 +766,6 @@ void Image::DestroyTexture() // Destroy the internal texture if (myTexture) { - // Make sure we have a valid context - priv::GraphicsContext Ctx; - GLuint Texture = static_cast(myTexture); GLCheck(glDeleteTextures(1, &Texture)); myTexture = 0; diff --git a/src/SFML/Graphics/PostFX.cpp b/src/SFML/Graphics/PostFX.cpp index cc5e6988..f7c8d9df 100644 --- a/src/SFML/Graphics/PostFX.cpp +++ b/src/SFML/Graphics/PostFX.cpp @@ -28,7 +28,7 @@ //////////////////////////////////////////////////////////// #include #include -#include +#include #include #include #include @@ -43,6 +43,9 @@ namespace sf PostFX::PostFX() : myShaderProgram(0) { + // Make sure that GLEW is initialized + EnsureGlewInit(); + // No filtering on frame buffer myFrameBuffer.SetSmooth(false); } @@ -74,12 +77,7 @@ PostFX::~PostFX() { // Destroy effect program if (myShaderProgram) - { - // Make sure we have a valid context - priv::GraphicsContext Ctx; - GLCheck(glDeleteObjectARB(myShaderProgram)); - } } @@ -264,8 +262,8 @@ PostFX& PostFX::operator =(const PostFX& Other) //////////////////////////////////////////////////////////// bool PostFX::CanUsePostFX() { - // Make sure we have a valid context - priv::GraphicsContext Ctx; + // Make sure that GLEW is initialized + EnsureGlewInit(); return glewIsSupported("GL_ARB_shading_language_100") != 0 && glewIsSupported("GL_ARB_shader_objects") != 0 && @@ -411,9 +409,6 @@ std::string PostFX::PreprocessEffect(std::istream& File) //////////////////////////////////////////////////////////// void PostFX::CreateProgram() { - // Make sure we have a valid context - priv::GraphicsContext Ctx; - // Check that we can use post-FX ! if (!CanUsePostFX()) { diff --git a/src/SFML/Graphics/RenderTarget.cpp b/src/SFML/Graphics/RenderTarget.cpp index f9d9096a..1c07bc09 100644 --- a/src/SFML/Graphics/RenderTarget.cpp +++ b/src/SFML/Graphics/RenderTarget.cpp @@ -27,7 +27,7 @@ //////////////////////////////////////////////////////////// #include #include -#include +#include #include diff --git a/src/SFML/Graphics/RenderWindow.cpp b/src/SFML/Graphics/RenderWindow.cpp index 8b11fa63..a2ddabe5 100644 --- a/src/SFML/Graphics/RenderWindow.cpp +++ b/src/SFML/Graphics/RenderWindow.cpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include @@ -113,9 +113,6 @@ Image RenderWindow::Capture() const // Set our window as the current target for rendering if (SetActive()) { - // Make sure we have a valid context - priv::GraphicsContext Ctx; - // Get pixels from the backbuffer std::vector Pixels(Width * Height * 4); Uint8* PixelsPtr = &Pixels[0]; diff --git a/src/SFML/Graphics/Shape.cpp b/src/SFML/Graphics/Shape.cpp index ca613f02..7dbb8854 100644 --- a/src/SFML/Graphics/Shape.cpp +++ b/src/SFML/Graphics/Shape.cpp @@ -26,7 +26,7 @@ // Headers //////////////////////////////////////////////////////////// #include -#include +#include #include diff --git a/src/SFML/Graphics/Sprite.cpp b/src/SFML/Graphics/Sprite.cpp index b5a52a8c..51e5520c 100644 --- a/src/SFML/Graphics/Sprite.cpp +++ b/src/SFML/Graphics/Sprite.cpp @@ -27,7 +27,7 @@ //////////////////////////////////////////////////////////// #include #include -#include +#include namespace sf diff --git a/src/SFML/Graphics/String.cpp b/src/SFML/Graphics/String.cpp index 89cfc30d..192a47cc 100644 --- a/src/SFML/Graphics/String.cpp +++ b/src/SFML/Graphics/String.cpp @@ -27,7 +27,7 @@ //////////////////////////////////////////////////////////// #include #include -#include +#include #include diff --git a/src/SFML/System/ThreadLocal.cpp b/src/SFML/System/ThreadLocal.cpp new file mode 100644 index 00000000..ae2ebf0b --- /dev/null +++ b/src/SFML/System/ThreadLocal.cpp @@ -0,0 +1,80 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + + +#if defined(SFML_SYSTEM_WINDOWS) + + #include + +#else + + #include + +#endif + + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// Default constructor +//////////////////////////////////////////////////////////// +ThreadLocal::ThreadLocal(void* Value) +{ + myImpl = new priv::ThreadLocalImpl; + SetValue(Value); +} + + +//////////////////////////////////////////////////////////// +/// Destructor +//////////////////////////////////////////////////////////// +ThreadLocal::~ThreadLocal() +{ + delete myImpl; +} + + +//////////////////////////////////////////////////////////// +/// Set the thread-specific value of the variable +//////////////////////////////////////////////////////////// +void ThreadLocal::SetValue(void* Value) +{ + myImpl->SetValue(Value); +} + + +//////////////////////////////////////////////////////////// +/// Retrieve the thread-specific value of the variable +//////////////////////////////////////////////////////////// +void* ThreadLocal::GetValue() const +{ + return myImpl->GetValue(); +} + +} // namespace sf diff --git a/src/SFML/Graphics/GraphicsContext.cpp b/src/SFML/System/Unix/ThreadLocalImpl.cpp similarity index 52% rename from src/SFML/Graphics/GraphicsContext.cpp rename to src/SFML/System/Unix/ThreadLocalImpl.cpp index da28c351..f5395963 100644 --- a/src/SFML/Graphics/GraphicsContext.cpp +++ b/src/SFML/System/Unix/ThreadLocalImpl.cpp @@ -25,31 +25,7 @@ //////////////////////////////////////////////////////////// // Headers //////////////////////////////////////////////////////////// -#include -#include - - -namespace -{ - //////////////////////////////////////////////////////////// - // One time initialization of 3rd party libraries. - // We use a global function with a static boolean rather - // than directly a global boolean, to avoid the randomness - // of global variables initializations across compile units. - //////////////////////////////////////////////////////////// - void InitGraphicsLibs() - { - static bool InitDone = false; - if (!InitDone) - { - // Initialize GLEW - glewInit(); - - InitDone = true; - } - } - -} +#include namespace sf @@ -57,36 +33,38 @@ namespace sf namespace priv { //////////////////////////////////////////////////////////// -/// Default constructor, activate the global context -/// if no other context is bound to the current thread +/// Default constructor -- allocate the storage //////////////////////////////////////////////////////////// -GraphicsContext::GraphicsContext() +ThreadLocalImpl::ThreadLocalImpl() { - // Activate the global context - if (!Context::IsContextActive()) - { - Context::GetDefault().SetActive(true); - myActivated = true; - } - else - { - myActivated = false; - } - - // Make sure third party libraries are initialized - InitGraphicsLibs(); + pthread_key_create(&myKey, NULL); } //////////////////////////////////////////////////////////// -/// Destructor, deactivate the global context -/// if no other context was previously bound to the current thread +/// Destructor -- free the storage //////////////////////////////////////////////////////////// -GraphicsContext::~GraphicsContext() +ThreadLocalImpl::~ThreadLocalImpl() { - // Deactivate the global context - if (myActivated) - Context::GetDefault().SetActive(false); + pthread_key_delete(myKey); +} + + +//////////////////////////////////////////////////////////// +/// Set the thread-specific value of the variable +//////////////////////////////////////////////////////////// +void ThreadLocalImpl::SetValue(void* Value) +{ + pthread_setspecific(myKey, Value); +} + + +//////////////////////////////////////////////////////////// +/// Retrieve the thread-specific value of the variable +//////////////////////////////////////////////////////////// +void* ThreadLocalImpl::GetValue() const +{ + return pthread_getspecific(myKey); } } // namespace priv diff --git a/src/SFML/System/Unix/ThreadLocalImpl.hpp b/src/SFML/System/Unix/ThreadLocalImpl.hpp new file mode 100644 index 00000000..3457bf63 --- /dev/null +++ b/src/SFML/System/Unix/ThreadLocalImpl.hpp @@ -0,0 +1,87 @@ +//////////////////////////////////////////////////////////// +// +// 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_THREADLOCALIMPL_HPP +#define SFML_THREADLOCALIMPL_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include + + +namespace sf +{ +namespace priv +{ +//////////////////////////////////////////////////////////// +/// Unix implementation of thread-local storage +//////////////////////////////////////////////////////////// +class ThreadLocalImpl : NonCopyable +{ +public : + + //////////////////////////////////////////////////////////// + /// Default constructor -- allocate the storage + /// + //////////////////////////////////////////////////////////// + ThreadLocalImpl(); + + //////////////////////////////////////////////////////////// + /// Destructor -- free the storage + /// + //////////////////////////////////////////////////////////// + ~ThreadLocalImpl(); + + //////////////////////////////////////////////////////////// + /// Set the thread-specific value of the variable + /// + /// \param Value : Value of the variable for this thread + /// + //////////////////////////////////////////////////////////// + void SetValue(void* Value); + + //////////////////////////////////////////////////////////// + /// Retrieve the thread-specific value of the variable + /// + /// \return Value of the variable for this thread + /// + //////////////////////////////////////////////////////////// + void* GetValue() const; + +private : + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + pthread_key_t myKey; ///< Index of our thread-local storage slot +}; + +} // namespace priv + +} // namespace sf + + +#endif // SFML_THREADLOCALIMPL_HPP diff --git a/src/SFML/System/Win32/ThreadLocalImpl.cpp b/src/SFML/System/Win32/ThreadLocalImpl.cpp new file mode 100644 index 00000000..0757c8b0 --- /dev/null +++ b/src/SFML/System/Win32/ThreadLocalImpl.cpp @@ -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. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + + +namespace sf +{ +namespace priv +{ +//////////////////////////////////////////////////////////// +/// Default constructor -- allocate the storage +//////////////////////////////////////////////////////////// +ThreadLocalImpl::ThreadLocalImpl() +{ + myIndex = TlsAlloc(); +} + + +//////////////////////////////////////////////////////////// +/// Destructor -- free the storage +//////////////////////////////////////////////////////////// +ThreadLocalImpl::~ThreadLocalImpl() +{ + TlsFree(myIndex); +} + + +//////////////////////////////////////////////////////////// +/// Set the thread-specific value of the variable +//////////////////////////////////////////////////////////// +void ThreadLocalImpl::SetValue(void* Value) +{ + TlsSetValue(myIndex, Value); +} + + +//////////////////////////////////////////////////////////// +/// Retrieve the thread-specific value of the variable +//////////////////////////////////////////////////////////// +void* ThreadLocalImpl::GetValue() const +{ + return TlsGetValue(myIndex); +} + +} // namespace priv + +} // namespace sf diff --git a/src/SFML/System/Win32/ThreadLocalImpl.hpp b/src/SFML/System/Win32/ThreadLocalImpl.hpp new file mode 100644 index 00000000..dc04ef26 --- /dev/null +++ b/src/SFML/System/Win32/ThreadLocalImpl.hpp @@ -0,0 +1,87 @@ +//////////////////////////////////////////////////////////// +// +// 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_THREADLOCALIMPL_HPP +#define SFML_THREADLOCALIMPL_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include + + +namespace sf +{ +namespace priv +{ +//////////////////////////////////////////////////////////// +/// Windows implementation of thread-local storage +//////////////////////////////////////////////////////////// +class ThreadLocalImpl : NonCopyable +{ +public : + + //////////////////////////////////////////////////////////// + /// Default constructor -- allocate the storage + /// + //////////////////////////////////////////////////////////// + ThreadLocalImpl(); + + //////////////////////////////////////////////////////////// + /// Destructor -- free the storage + /// + //////////////////////////////////////////////////////////// + ~ThreadLocalImpl(); + + //////////////////////////////////////////////////////////// + /// Set the thread-specific value of the variable + /// + /// \param Value : Value of the variable for this thread + /// + //////////////////////////////////////////////////////////// + void SetValue(void* Value); + + //////////////////////////////////////////////////////////// + /// Retrieve the thread-specific value of the variable + /// + /// \return Value of the variable for this thread + /// + //////////////////////////////////////////////////////////// + void* GetValue() const; + +private : + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + DWORD myIndex; ///< Index of our thread-local storage slot +}; + +} // namespace priv + +} // namespace sf + + +#endif // SFML_THREADLOCALIMPL_HPP diff --git a/src/SFML/Window/Context.cpp b/src/SFML/Window/Context.cpp index 3f3a24a0..921e1e85 100644 --- a/src/SFML/Window/Context.cpp +++ b/src/SFML/Window/Context.cpp @@ -26,125 +26,38 @@ // Headers //////////////////////////////////////////////////////////// #include -#include -#include -#include - - -#if defined(SFML_SYSTEM_WINDOWS) - - #include - typedef sf::priv::ContextWGL ContextType; - -#elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD) - - #include - typedef sf::priv::ContextGLX ContextType; - -#elif defined(SFML_SYSTEM_MACOS) - - #include - typedef sf::priv::ContextAGL ContextType; - -#endif +#include namespace sf { //////////////////////////////////////////////////////////// -/// Create a new context, not associated to a window -//////////////////////////////////////////////////////////// -Context* Context::New() -{ - ContextType* Shared = static_cast(&GetDefault()); - return new ContextType(Shared); -} - - -//////////////////////////////////////////////////////////// -/// Create a new context attached to a window -//////////////////////////////////////////////////////////// -Context* Context::New(const priv::WindowImpl* Owner, unsigned int BitsPerPixel, const ContextSettings& Settings) -{ - ContextType* Shared = static_cast(&GetDefault()); - ContextType* NewContext = new ContextType(Shared, Owner, BitsPerPixel, Settings); - - // Enable antialiasing if needed - if (NewContext->GetSettings().AntialiasingLevel > 0) - glEnable(GL_MULTISAMPLE_ARB); - - return NewContext; -} - - -//////////////////////////////////////////////////////////// -/// Check if a context is active on the current thread -//////////////////////////////////////////////////////////// -bool Context::IsContextActive() -{ - return ContextType::IsContextActive(); -} - - -//////////////////////////////////////////////////////////// -/// Return the default context -//////////////////////////////////////////////////////////// -Context& Context::GetDefault() -{ - static ContextType DefaultContext(NULL); - - return DefaultContext; -} - - -//////////////////////////////////////////////////////////// -/// Destructor -//////////////////////////////////////////////////////////// -Context::~Context() -{ - // Nothing to do -} - - -//////////////////////////////////////////////////////////// -/// Get the settings of the context -//////////////////////////////////////////////////////////// -const ContextSettings& Context::GetSettings() const -{ - return mySettings; -} - - -//////////////////////////////////////////////////////////// -/// Activate or deactivate the context as the current target -/// for rendering -//////////////////////////////////////////////////////////// -bool Context::SetActive(bool Active) -{ - return MakeCurrent(Active); -} - - -//////////////////////////////////////////////////////////// -/// Default constructor +/// Default constructor -- creates and activates the context //////////////////////////////////////////////////////////// Context::Context() { - + myContext = priv::ContextGL::New(); + SetActive(true); } //////////////////////////////////////////////////////////// -/// Evaluate a pixel format configuration. -/// This functions can be used by implementations that have -/// several valid formats and want to get the best one +/// Destructor -- deactivates and destroys the context //////////////////////////////////////////////////////////// -int Context::EvaluateFormat(unsigned int BitsPerPixel, const ContextSettings& Settings, int ColorBits, int DepthBits, int StencilBits, int Antialiasing) +Context::~Context() { - return abs(static_cast(BitsPerPixel - ColorBits)) + - abs(static_cast(Settings.DepthBits - DepthBits)) + - abs(static_cast(Settings.StencilBits - StencilBits)) + - abs(static_cast(Settings.AntialiasingLevel - Antialiasing)); + SetActive(false); + delete myContext; } + +//////////////////////////////////////////////////////////// +/// Activate or deactivate explicitely the context +//////////////////////////////////////////////////////////// +void Context::SetActive(bool Active) +{ + myContext->SetActive(Active); +} + + } // namespace sf diff --git a/src/SFML/Window/ContextGL.cpp b/src/SFML/Window/ContextGL.cpp new file mode 100644 index 00000000..b49ef02b --- /dev/null +++ b/src/SFML/Window/ContextGL.cpp @@ -0,0 +1,178 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include +#include +#include + + +#if defined(SFML_SYSTEM_WINDOWS) + + #include + typedef sf::priv::ContextWGL ContextType; + +#elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD) + + #include + typedef sf::priv::ContextGLX ContextType; + +#elif defined(SFML_SYSTEM_MACOS) + + #include + typedef sf::priv::ContextAGL ContextType; + +#endif + + +//////////////////////////////////////////////////////////// +// Private data +//////////////////////////////////////////////////////////// +namespace +{ + // This thread-local variable will hold the "gloabl" context for each thread + sf::ThreadLocalPtr ThreadContext(NULL); + + // Now we create two global contexts. + // The first one is the reference context: it will be shared with every other + // context, and he can't be activated if we want the sharing operation to always succeed. + // That 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); +} + + +namespace sf +{ +namespace priv +{ +//////////////////////////////////////////////////////////// +/// Create a new context, not associated to a window +//////////////////////////////////////////////////////////// +ContextGL* ContextGL::New() +{ + return new ContextType(&ReferenceContext); +} + + +//////////////////////////////////////////////////////////// +/// Create a new context attached to a window +//////////////////////////////////////////////////////////// +ContextGL* ContextGL::New(const WindowImpl* Owner, unsigned int BitsPerPixel, const ContextSettings& Settings) +{ + ContextType* Context = new ContextType(&ReferenceContext, Owner, BitsPerPixel, Settings); + + // Enable antialiasing if needed + if (Context->GetSettings().AntialiasingLevel > 0) + glEnable(GL_MULTISAMPLE_ARB); + + return Context; +} + + +//////////////////////////////////////////////////////////// +/// Destructor +//////////////////////////////////////////////////////////// +ContextGL::~ContextGL() +{ + if (ThreadContext == this) + { + ThreadContext = NULL; + } + else if (ThreadContext != NULL) + { + ThreadContext->SetActive(true); + } +} + + +//////////////////////////////////////////////////////////// +/// Get the settings of the context +//////////////////////////////////////////////////////////// +const ContextSettings& ContextGL::GetSettings() const +{ + return mySettings; +} + + +//////////////////////////////////////////////////////////// +/// Activate or deactivate the context as the current target +/// for rendering +//////////////////////////////////////////////////////////// +bool ContextGL::SetActive(bool Active) +{ + if (MakeCurrent(Active)) + { + if (Active && (ThreadContext == NULL)) + { + // If this is the first context to be activated on this thread, make + // it the reference context for the whole thread + ThreadContext = this; + } + else if (!Active && (ThreadContext != NULL) && (ThreadContext != this)) + { + // Activate the reference context for this thread to ensure + // that there is always an active context for subsequent graphics operations + ThreadContext->SetActive(true); + } + + return true; + } + else + { + return false; + } +} + + +//////////////////////////////////////////////////////////// +/// Default constructor +//////////////////////////////////////////////////////////// +ContextGL::ContextGL() +{ + // Nothing to do +} + + +//////////////////////////////////////////////////////////// +/// Evaluate a pixel format configuration. +/// This functions can be used by implementations that have +/// several valid formats and want to get the best one +//////////////////////////////////////////////////////////// +int ContextGL::EvaluateFormat(unsigned int BitsPerPixel, const ContextSettings& Settings, int ColorBits, int DepthBits, int StencilBits, int Antialiasing) +{ + return abs(static_cast(BitsPerPixel - ColorBits)) + + abs(static_cast(Settings.DepthBits - DepthBits)) + + abs(static_cast(Settings.StencilBits - StencilBits)) + + abs(static_cast(Settings.AntialiasingLevel - Antialiasing)); +} + +} // namespace priv + +} // namespace sf diff --git a/src/SFML/Window/ContextGL.hpp b/src/SFML/Window/ContextGL.hpp new file mode 100644 index 00000000..1ae5c7ff --- /dev/null +++ b/src/SFML/Window/ContextGL.hpp @@ -0,0 +1,156 @@ +//////////////////////////////////////////////////////////// +// +// 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_CONTEXTGL_HPP +#define SFML_CONTEXTGL_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include + + +namespace sf +{ +namespace priv +{ +class WindowImpl; + +//////////////////////////////////////////////////////////// +/// Abstract class representing an OpenGL context +//////////////////////////////////////////////////////////// +class ContextGL : NonCopyable +{ +public : + + //////////////////////////////////////////////////////////// + /// Create a new context, not associated to a window + /// + /// \return Pointer to the created context + /// + //////////////////////////////////////////////////////////// + static ContextGL* New(); + + //////////////////////////////////////////////////////////// + /// Create a new context attached to a window + /// + /// \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 + /// + //////////////////////////////////////////////////////////// + static ContextGL* New(const WindowImpl* Owner, unsigned int BitsPerPixel, const ContextSettings& Settings); + +public : + + //////////////////////////////////////////////////////////// + /// Virtual destructor + /// + //////////////////////////////////////////////////////////// + virtual ~ContextGL(); + + //////////////////////////////////////////////////////////// + /// Get the settings of the context + /// + /// \return Structure containing the settings + /// + //////////////////////////////////////////////////////////// + const ContextSettings& GetSettings() const; + + //////////////////////////////////////////////////////////// + /// Activate or deactivate the context as the current target + /// for rendering + /// + /// \param Active : True to activate, false to deactivate + /// + /// \return True if operation was successful, false otherwise + /// + //////////////////////////////////////////////////////////// + bool SetActive(bool Active); + + //////////////////////////////////////////////////////////// + /// Display the contents of the context + /// + //////////////////////////////////////////////////////////// + virtual void Display() = 0; + + //////////////////////////////////////////////////////////// + /// Enable / disable vertical synchronization + /// + /// \param Enabled : True to enable v-sync, false to deactivate + /// + //////////////////////////////////////////////////////////// + virtual void UseVerticalSync(bool Enabled) = 0; + +protected : + + //////////////////////////////////////////////////////////// + /// Default constructor + /// + //////////////////////////////////////////////////////////// + ContextGL(); + + //////////////////////////////////////////////////////////// + /// Make this context the current one + /// + /// \param Active : True to activate, false to deactivate + /// + /// \return True on success, false if any error happened + /// + //////////////////////////////////////////////////////////// + virtual bool MakeCurrent(bool Active) = 0; + + //////////////////////////////////////////////////////////// + /// Evaluate a pixel format configuration. + /// This functions can be used by implementations that have + /// several valid formats and want to get the best one + /// + /// \param BitsPerPixel : Requested pixel depth (bits per pixel) + /// \param Settings : Requested additionnal settings + /// \param ColorBits : Color bits of the configuration to evaluate + /// \param DepthBits : Depth bits of the configuration to evaluate + /// \param StencilBits : Stencil bits of the configuration to evaluate + /// \param Antialiasing : Antialiasing level of the configuration to evaluate + /// + /// \return Score of the configuration : the lower the better + /// + //////////////////////////////////////////////////////////// + static int EvaluateFormat(unsigned int BitsPerPixel, const ContextSettings& Settings, int ColorBits, int DepthBits, int StencilBits, int Antialiasing); + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + ContextSettings mySettings; ///< Creation settings of the context +}; + +} // namespace priv + +} // namespace sf + + +#endif // SFML_CONTEXTGL_HPP diff --git a/src/SFML/Window/Linux/ContextGLX.cpp b/src/SFML/Window/Linux/ContextGLX.cpp index 063c4997..f134b59d 100644 --- a/src/SFML/Window/Linux/ContextGLX.cpp +++ b/src/SFML/Window/Linux/ContextGLX.cpp @@ -27,9 +27,8 @@ //////////////////////////////////////////////////////////// #include #include -#include +#include #include -#include #include @@ -59,6 +58,10 @@ myOwnsWindow(true) // Create the context CreateContext(Shared, VideoMode::GetDesktopMode().BitsPerPixel, ContextSettings(0, 0, 0)); + + // Activate the context + if (Shared) + SetActive(true); } @@ -76,6 +79,10 @@ myOwnsWindow(false) // Create the context if (myWindow) CreateContext(Shared, BitsPerPixel, Settings); + + // Activate the context + if (Shared) + SetActive(true); } diff --git a/src/SFML/Window/Win32/ContextWGL.cpp b/src/SFML/Window/Win32/ContextWGL.cpp index 4dcf563b..c4af5231 100644 --- a/src/SFML/Window/Win32/ContextWGL.cpp +++ b/src/SFML/Window/Win32/ContextWGL.cpp @@ -27,7 +27,7 @@ //////////////////////////////////////////////////////////// #include #include -#include +#include #include #include @@ -45,7 +45,8 @@ myDC (NULL), myContext (NULL), myOwnsWindow(true) { - // ------------ TEMP ------------ + // TODO : try to create a bitmap in memory instead of a dummy window + // Create a dummy window (disabled and hidden) myWindow = CreateWindowA("STATIC", "", WS_POPUP | WS_DISABLED, 0, 0, 1, 1, NULL, NULL, GetModuleHandle(NULL), NULL); ShowWindow(myWindow, SW_HIDE); @@ -54,7 +55,10 @@ myOwnsWindow(true) // Create the context if (myDC) CreateContext(Shared, VideoMode::GetDesktopMode().BitsPerPixel, ContextSettings(0, 0, 0)); - // ------------ TEMP ------------ + + // Activate the context + if (Shared) + SetActive(true); } @@ -74,6 +78,10 @@ myOwnsWindow(false) // Create the context if (myDC) CreateContext(Shared, BitsPerPixel, Settings); + + // Activate the context + if (Shared) + SetActive(true); } @@ -304,7 +312,10 @@ void ContextWGL::CreateContext(ContextWGL* Shared, unsigned int BitsPerPixel, co // Share this context with others if (SharedContext) - wglShareLists(SharedContext, myContext); + { + if (!wglShareLists(SharedContext, myContext)) + std::cerr << "Failed to share the OpenGL context" << std::endl; + } } } diff --git a/src/SFML/Window/Win32/ContextWGL.hpp b/src/SFML/Window/Win32/ContextWGL.hpp index 32aaaf7c..36a1639f 100644 --- a/src/SFML/Window/Win32/ContextWGL.hpp +++ b/src/SFML/Window/Win32/ContextWGL.hpp @@ -28,7 +28,7 @@ //////////////////////////////////////////////////////////// // Headers //////////////////////////////////////////////////////////// -#include +#include #include @@ -39,7 +39,7 @@ namespace priv //////////////////////////////////////////////////////////// /// Windows (WGL) implementation of OpenGL contexts //////////////////////////////////////////////////////////// -class ContextWGL : public Context +class ContextWGL : public ContextGL { public : diff --git a/src/SFML/Window/Window.cpp b/src/SFML/Window/Window.cpp index c94280df..1320065e 100644 --- a/src/SFML/Window/Window.cpp +++ b/src/SFML/Window/Window.cpp @@ -26,6 +26,7 @@ // Headers //////////////////////////////////////////////////////////// #include +#include #include #include #include @@ -142,11 +143,11 @@ void Window::Create(VideoMode Mode, const std::string& Title, unsigned long Wind // Make sure another context is bound, so that: // - the context creation can request OpenGL extensions if necessary // - myContext can safely be destroyed (it's no longer bound) - Context::GetDefault().SetActive(true); + Context Ctx; // Recreate the context delete myContext; - myContext = Context::New(myWindow, Mode.BitsPerPixel, Settings); + myContext = priv::ContextGL::New(myWindow, Mode.BitsPerPixel, Settings); Initialize(); } @@ -164,11 +165,11 @@ void Window::Create(WindowHandle Handle, const ContextSettings& Settings) // Make sure another context is bound, so that: // - the context creation can request OpenGL extensions if necessary // - myContext can safely be destroyed (it's no longer bound) - Context::GetDefault().SetActive(true); + Context Ctx; // Recreate the context delete myContext; - myContext = Context::New(myWindow, VideoMode::GetDesktopMode().BitsPerPixel, Settings); + myContext = priv::ContextGL::New(myWindow, VideoMode::GetDesktopMode().BitsPerPixel, Settings); Initialize(); } @@ -183,9 +184,6 @@ void Window::Close() { if (myContext) { - // Make sure that our context is no longer bound - Context::GetDefault().SetActive(true); - // Delete the context delete myContext; myContext = NULL;