From 91e1743516377e16d675b6486301aeba5b20bef8 Mon Sep 17 00:00:00 2001 From: Laurent Gomila Date: Tue, 8 Jan 2013 22:24:43 +0100 Subject: [PATCH] Changed Texture::bind and Shader::bind to be static functions, that can accept a null argument --- include/SFML/Graphics/Shader.hpp | 28 ++++++---- include/SFML/Graphics/Texture.hpp | 64 ++++++++++++++-------- src/SFML/Graphics/RenderTarget.cpp | 10 +--- src/SFML/Graphics/Shader.cpp | 23 +++++--- src/SFML/Graphics/Texture.cpp | 88 +++++++++++++++++------------- 5 files changed, 125 insertions(+), 88 deletions(-) diff --git a/include/SFML/Graphics/Shader.hpp b/include/SFML/Graphics/Shader.hpp index d3a7a1047..3fb1da1fd 100644 --- a/include/SFML/Graphics/Shader.hpp +++ b/include/SFML/Graphics/Shader.hpp @@ -448,19 +448,27 @@ public : void setParameter(const std::string& name, CurrentTextureType); //////////////////////////////////////////////////////////// - /// \brief Bind the shader for rendering (activate it) + /// \brief Bind a shader for rendering + /// + /// This function is not part of the graphics API, it mustn't be + /// used when drawing SFML entities. It must be used only if you + /// mix sf::Shader with OpenGL code. /// - /// This function is normally for internal use only, unless - /// you want to use the shader with a custom OpenGL rendering - /// instead of a SFML drawable. /// \code - /// window.setActive(); - /// shader.bind(); - /// ... render OpenGL geometry ... + /// sf::Shader s1, s2; + /// ... + /// sf::Shader::bind(&s1); + /// // draw OpenGL stuff that use s1... + /// sf::Shader::bind(&s2); + /// // draw OpenGL stuff that use s2... + /// sf::Shader::bind(NULL); + /// // draw OpenGL stuff that use no shader... /// \endcode /// + /// \param shader Shader to bind, can be null to use no shader + /// //////////////////////////////////////////////////////////// - void bind() const; + static void bind(const Shader* shader); //////////////////////////////////////////////////////////// /// \brief Tell whether or not the system supports shaders @@ -607,9 +615,9 @@ private : /// sf::Shader can also be used directly as a raw shader for /// custom OpenGL geometry. /// \code -/// window.setActive(); -/// shader.bind(); +/// sf::Shader::bind(&shader); /// ... render OpenGL geometry ... +/// sf::Shader::bind(NULL); /// \endcode /// //////////////////////////////////////////////////////////// diff --git a/include/SFML/Graphics/Texture.hpp b/include/SFML/Graphics/Texture.hpp index 3816b92b6..eb946e3df 100644 --- a/include/SFML/Graphics/Texture.hpp +++ b/include/SFML/Graphics/Texture.hpp @@ -350,28 +350,6 @@ public : //////////////////////////////////////////////////////////// void update(const Window& window, unsigned int x, unsigned int y); - //////////////////////////////////////////////////////////// - /// \brief Activate the texture for rendering - /// - /// This function is mainly used internally by the SFML - /// rendering system. However it can be useful when - /// using sf::Texture together with OpenGL code (this function - /// is equivalent to glBindTexture). - /// - /// The \a coordinateType argument controls how texture - /// coordinates will be interpreted. If Normalized (the default), they - /// must be in range [0 .. 1], which is the default way of handling - /// texture coordinates with OpenGL. If Pixels, they must be given - /// in pixels (range [0 .. size]). This mode is used internally by - /// the graphics classes of SFML, it makes the definition of texture - /// coordinates more intuitive for the high-level API, users don't need - /// to compute normalized values. - /// - /// \param coordinateType Type of texture coordinates to use - /// - //////////////////////////////////////////////////////////// - void bind(CoordinateType coordinateType = Normalized) const; - //////////////////////////////////////////////////////////// /// \brief Enable or disable the smooth filter /// @@ -442,6 +420,39 @@ public : //////////////////////////////////////////////////////////// Texture& operator =(const Texture& right); + //////////////////////////////////////////////////////////// + /// \brief Bind a texture for rendering + /// + /// This function is not part of the graphics API, it mustn't be + /// used when drawing SFML entities. It must be used only if you + /// mix sf::Texture with OpenGL code. + /// + /// \code + /// sf::Texture t1, t2; + /// ... + /// sf::Texture::bind(&t1); + /// // draw OpenGL stuff that use t1... + /// sf::Texture::bind(&t2); + /// // draw OpenGL stuff that use t2... + /// sf::Texture::bind(NULL); + /// // draw OpenGL stuff that use no texture... + /// \endcode + /// + /// The \a coordinateType argument controls how texture + /// coordinates will be interpreted. If Normalized (the default), they + /// must be in range [0 .. 1], which is the default way of handling + /// texture coordinates with OpenGL. If Pixels, they must be given + /// in pixels (range [0 .. size]). This mode is used internally by + /// the graphics classes of SFML, it makes the definition of texture + /// coordinates more intuitive for the high-level API, users don't need + /// to compute normalized values. + /// + /// \param texture Pointer to the texture to bind, can be null to use no texture + /// \param coordinateType Type of texture coordinates to use + /// + //////////////////////////////////////////////////////////// + static void bind(const Texture* texture, CoordinateType coordinateType = Normalized); + //////////////////////////////////////////////////////////// /// \brief Get the maximum texture size allowed /// @@ -577,6 +588,15 @@ private : /// /// \endcode /// +/// Like sf::Shader that can be used as a raw OpenGL shader, +/// sf::Texture can also be used directly as a raw texture for +/// custom OpenGL geometry. +/// \code +/// sf::Texture::bind(&texture); +/// ... render OpenGL geometry ... +/// sf::Texture::bind(NULL); +/// \endcode +/// /// \see sf::Sprite, sf::Image, sf::RenderTexture /// //////////////////////////////////////////////////////////// diff --git a/src/SFML/Graphics/RenderTarget.cpp b/src/SFML/Graphics/RenderTarget.cpp index 860b8a490..3b37010df 100644 --- a/src/SFML/Graphics/RenderTarget.cpp +++ b/src/SFML/Graphics/RenderTarget.cpp @@ -391,10 +391,7 @@ void RenderTarget::applyTransform(const Transform& transform) //////////////////////////////////////////////////////////// void RenderTarget::applyTexture(const Texture* texture) { - if (texture) - texture->bind(Texture::Pixels); - else - glCheck(glBindTexture(GL_TEXTURE_2D, 0)); + Texture::bind(texture, Texture::Pixels); m_cache.lastTextureId = texture ? texture->m_cacheId : 0; } @@ -403,10 +400,7 @@ void RenderTarget::applyTexture(const Texture* texture) //////////////////////////////////////////////////////////// void RenderTarget::applyShader(const Shader* shader) { - if (shader) - shader->bind(); - else - glCheck(glUseProgramObjectARB(0)); + Shader::bind(shader); } } // namespace sf diff --git a/src/SFML/Graphics/Shader.cpp b/src/SFML/Graphics/Shader.cpp index be6dc1d8a..c9654359e 100644 --- a/src/SFML/Graphics/Shader.cpp +++ b/src/SFML/Graphics/Shader.cpp @@ -410,21 +410,26 @@ void Shader::setParameter(const std::string& name, CurrentTextureType) //////////////////////////////////////////////////////////// -void Shader::bind() const +void Shader::bind(const Shader* shader) { - if (m_shaderProgram) - { - ensureGlContext(); + ensureGlContext(); + if (shader && shader->m_shaderProgram) + { // Enable the program - glCheck(glUseProgramObjectARB(m_shaderProgram)); + glCheck(glUseProgramObjectARB(shader->m_shaderProgram)); // Bind the textures - bindTextures(); + shader->bindTextures(); // Bind the current texture - if (m_currentTexture != -1) - glCheck(glUniform1iARB(m_currentTexture, 0)); + if (shader->m_currentTexture != -1) + glCheck(glUniform1iARB(shader->m_currentTexture, 0)); + } + else + { + // Bind no shader + glCheck(glUseProgramObjectARB(0)); } } @@ -550,7 +555,7 @@ void Shader::bindTextures() const GLint index = static_cast(i + 1); glCheck(glUniform1iARB(it->first, index)); glCheck(glActiveTextureARB(GL_TEXTURE0_ARB + index)); - it->second->bind(); + Texture::bind(it->second); ++it; } diff --git a/src/SFML/Graphics/Texture.cpp b/src/SFML/Graphics/Texture.cpp index 5b0db3395..344ed841a 100644 --- a/src/SFML/Graphics/Texture.cpp +++ b/src/SFML/Graphics/Texture.cpp @@ -373,45 +373,6 @@ void Texture::update(const Window& window, unsigned int x, unsigned int y) } -//////////////////////////////////////////////////////////// -void Texture::bind(CoordinateType coordinateType) const -{ - // Bind the texture - glCheck(glBindTexture(GL_TEXTURE_2D, m_texture)); - - // Check if we need to define a special texture matrix - if (m_texture && ((coordinateType == Pixels) || m_pixelsFlipped)) - { - GLfloat matrix[16] = {1.f, 0.f, 0.f, 0.f, - 0.f, 1.f, 0.f, 0.f, - 0.f, 0.f, 1.f, 0.f, - 0.f, 0.f, 0.f, 1.f}; - - // If non-normalized coordinates (= pixels) are requested, we need to - // setup scale factors that convert the range [0 .. size] to [0 .. 1] - if (coordinateType == Pixels) - { - matrix[0] = 1.f / m_actualSize.x; - matrix[5] = 1.f / m_actualSize.y; - } - - // If pixels are flipped we must invert the Y axis - if (m_pixelsFlipped) - { - matrix[5] = -matrix[5]; - matrix[13] = static_cast(m_size.y / m_actualSize.y); - } - - // Load the matrix - glCheck(glMatrixMode(GL_TEXTURE)); - glCheck(glLoadMatrixf(matrix)); - - // Go back to model-view mode (sf::RenderTarget relies on it) - glCheck(glMatrixMode(GL_MODELVIEW)); - } -} - - //////////////////////////////////////////////////////////// void Texture::setSmooth(bool smooth) { @@ -470,6 +431,55 @@ bool Texture::isRepeated() const } +//////////////////////////////////////////////////////////// +void Texture::bind(const Texture* texture, CoordinateType coordinateType) +{ + ensureGlContext(); + + if (texture && texture->m_texture) + { + // Bind the texture + glCheck(glBindTexture(GL_TEXTURE_2D, texture->m_texture)); + + // Check if we need to define a special texture matrix + if ((coordinateType == Pixels) || texture->m_pixelsFlipped) + { + GLfloat matrix[16] = {1.f, 0.f, 0.f, 0.f, + 0.f, 1.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + 0.f, 0.f, 0.f, 1.f}; + + // If non-normalized coordinates (= pixels) are requested, we need to + // setup scale factors that convert the range [0 .. size] to [0 .. 1] + if (coordinateType == Pixels) + { + matrix[0] = 1.f / texture->m_actualSize.x; + matrix[5] = 1.f / texture->m_actualSize.y; + } + + // If pixels are flipped we must invert the Y axis + if (texture->m_pixelsFlipped) + { + matrix[5] = -matrix[5]; + matrix[13] = static_cast(texture->m_size.y / texture->m_actualSize.y); + } + + // Load the matrix + glCheck(glMatrixMode(GL_TEXTURE)); + glCheck(glLoadMatrixf(matrix)); + + // Go back to model-view mode (sf::RenderTarget relies on it) + glCheck(glMatrixMode(GL_MODELVIEW)); + } + } + else + { + // Bind no texture + glCheck(glBindTexture(GL_TEXTURE_2D, 0)); + } +} + + //////////////////////////////////////////////////////////// unsigned int Texture::getMaximumSize() {