diff --git a/include/SFML/Graphics/Image.hpp b/include/SFML/Graphics/Image.hpp index a696db81b..63d8b843f 100644 --- a/include/SFML/Graphics/Image.hpp +++ b/include/SFML/Graphics/Image.hpp @@ -37,6 +37,7 @@ namespace sf { +class Renderer; class RenderImage; class RenderWindow; @@ -291,6 +292,7 @@ public : private : + friend class Renderer; friend class RenderImage; //////////////////////////////////////////////////////////// @@ -315,6 +317,12 @@ private : //////////////////////////////////////////////////////////// void EnsureArrayUpdate() const; + //////////////////////////////////////////////////////////// + /// Make sure that the image is ready to be used + /// + //////////////////////////////////////////////////////////// + void Use() const; + //////////////////////////////////////////////////////////// /// Reset the image attributes /// diff --git a/include/SFML/Graphics/Shader.hpp b/include/SFML/Graphics/Shader.hpp index a70b8ce4f..fe0396455 100644 --- a/include/SFML/Graphics/Shader.hpp +++ b/include/SFML/Graphics/Shader.hpp @@ -38,6 +38,8 @@ namespace sf { +class Renderer; + //////////////////////////////////////////////////////////// /// \brief Pixel/fragment shader class /// @@ -317,6 +319,8 @@ public : private : + friend class Renderer; + //////////////////////////////////////////////////////////// /// \brief Create the program and attach the shaders /// @@ -325,6 +329,25 @@ private : //////////////////////////////////////////////////////////// bool CompileProgram(); + //////////////////////////////////////////////////////////// + /// \brief Bind all the textures used by the shader + /// + /// This function each texture to a different unit, and + /// updates the corresponding variables in the shader accordingly. + /// + //////////////////////////////////////////////////////////// + void BindTextures() const; + + //////////////////////////////////////////////////////////// + /// \brief Make sure that the shader is ready to be used + /// + /// This function is called by the Renderer class, to make + /// sure that the shader's parameters are properly applied + /// even when Use() is not called due to internal optimizations. + /// + //////////////////////////////////////////////////////////// + void Use() const; + //////////////////////////////////////////////////////////// // Types //////////////////////////////////////////////////////////// diff --git a/src/SFML/Graphics/Image.cpp b/src/SFML/Graphics/Image.cpp index cb7c57de2..cd23d1781 100644 --- a/src/SFML/Graphics/Image.cpp +++ b/src/SFML/Graphics/Image.cpp @@ -42,15 +42,15 @@ namespace sf /// Default constructor //////////////////////////////////////////////////////////// Image::Image() : -myWidth (0), -myHeight (0), -myTextureWidth (0), -myTextureHeight (0), -myTexture (0), -myIsSmooth (true), -myTextureUpdated (true), -myArrayUpdated (true), -myPixelsFlipped (false) +myWidth (0), +myHeight (0), +myTextureWidth (0), +myTextureHeight (0), +myTexture (0), +myIsSmooth (true), +myTextureUpdated(true), +myArrayUpdated (true), +myPixelsFlipped (false) { } @@ -387,12 +387,12 @@ void Image::SetPixel(unsigned int x, unsigned int y, const Color& color) EnsureArrayUpdate(); // Check if pixel is whithin the image bounds - if ((x >= myWidth) || (y >= myHeight)) + /*if ((x >= myWidth) || (y >= myHeight)) { Err() << "Cannot set pixel (" << x << "," << y << ") for image " << "(width = " << myWidth << ", height = " << myHeight << ")" << std::endl; return; - } + }*/ myPixels[x + y * myWidth] = color; @@ -723,10 +723,6 @@ void Image::EnsureArrayUpdate() const { if (!myArrayUpdated) { - // First make sure the texture is up-to-date - // (may not be the case if an external update has been scheduled) - EnsureTextureUpdate(); - // Save the previous texture GLint previous; GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous)); @@ -779,6 +775,15 @@ void Image::EnsureArrayUpdate() const } +//////////////////////////////////////////////////////////// +/// Make sure that the image is ready to be used +//////////////////////////////////////////////////////////// +void Image::Use() const +{ + EnsureTextureUpdate(); +} + + //////////////////////////////////////////////////////////// /// Reset the image attributes //////////////////////////////////////////////////////////// diff --git a/src/SFML/Graphics/Renderer.cpp b/src/SFML/Graphics/Renderer.cpp index 886abf829..b4889a2df 100644 --- a/src/SFML/Graphics/Renderer.cpp +++ b/src/SFML/Graphics/Renderer.cpp @@ -248,6 +248,12 @@ void Renderer::SetTexture(const Image* texture) myTexture = texture; myTextureIsValid = true; } + else if (texture) + { + // If the texture was already the current one, make sure that + // it is synchronized (in case it was modified since last use) + texture->Use(); + } } @@ -269,6 +275,12 @@ void Renderer::SetShader(const Shader* shader) myShaderIsValid = true; } } + else if (shader) + { + // If the shader was already the current one, make sure that + // it is synchronized (in case it was modified since last use) + shader->Use(); + } } diff --git a/src/SFML/Graphics/Shader.cpp b/src/SFML/Graphics/Shader.cpp index 337a30fe3..162810492 100644 --- a/src/SFML/Graphics/Shader.cpp +++ b/src/SFML/Graphics/Shader.cpp @@ -245,15 +245,7 @@ void Shader::Bind() const GLCheck(glUseProgramObjectARB(myShaderProgram)); // Bind the textures - TextureTable::const_iterator it = myTextures.begin(); - for (std::size_t i = 0; i < myTextures.size(); ++i) - { - GLint index = static_cast(i + 1); - GLCheck(glUniform1iARB(it->first, index)); - GLCheck(glActiveTextureARB(GL_TEXTURE0_ARB + index)); - it->second->Bind(); - it++; - } + BindTextures(); // Make sure that the texture unit which is left active is the number 0 GLCheck(glActiveTextureARB(GL_TEXTURE0_ARB)); @@ -397,4 +389,26 @@ bool Shader::CompileProgram() return true; } + +//////////////////////////////////////////////////////////// +void Shader::BindTextures() const +{ + TextureTable::const_iterator it = myTextures.begin(); + for (std::size_t i = 0; i < myTextures.size(); ++i) + { + GLint index = static_cast(i + 1); + GLCheck(glUniform1iARB(it->first, index)); + GLCheck(glActiveTextureARB(GL_TEXTURE0_ARB + index)); + it->second->Bind(); + it++; + } +} + + +//////////////////////////////////////////////////////////// +void Shader::Use() const +{ + BindTextures(); +} + } // namespace sf