diff options
Diffstat (limited to 'src/SFML/Graphics/Texture.cpp')
-rw-r--r-- | src/SFML/Graphics/Texture.cpp | 118 |
1 files changed, 114 insertions, 4 deletions
diff --git a/src/SFML/Graphics/Texture.cpp b/src/SFML/Graphics/Texture.cpp index 4be52e7..a3e813f 100644 --- a/src/SFML/Graphics/Texture.cpp +++ b/src/SFML/Graphics/Texture.cpp @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org) +// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org) // // 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. @@ -58,7 +58,15 @@ namespace // Create a temporary context in case the user queries // the size before a GlResource is created, thus // initializing the shared context - sf::Context context; + if (!sf::Context::getActiveContext()) + { + sf::Context context; + + GLint size; + glCheck(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size)); + + return static_cast<unsigned int>(size); + } GLint size; glCheck(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size)); @@ -76,9 +84,11 @@ m_size (0, 0), m_actualSize (0, 0), m_texture (0), m_isSmooth (false), +m_sRgb (false), m_isRepeated (false), m_pixelsFlipped(false), m_fboAttachment(false), +m_hasMipmap (false), m_cacheId (getUniqueId()) { } @@ -90,9 +100,11 @@ m_size (0, 0), m_actualSize (0, 0), m_texture (0), m_isSmooth (copy.m_isSmooth), +m_sRgb (copy.m_sRgb), m_isRepeated (copy.m_isRepeated), m_pixelsFlipped(false), m_fboAttachment(false), +m_hasMipmap (false), m_cacheId (getUniqueId()) { if (copy.m_texture) @@ -177,15 +189,38 @@ bool Texture::create(unsigned int width, unsigned int height) } } + static bool textureSrgb = GLEXT_texture_sRGB; + + if (m_sRgb && !textureSrgb) + { + static bool warned = false; + + if (!warned) + { +#ifndef SFML_OPENGL_ES + err() << "OpenGL extension EXT_texture_sRGB unavailable" << std::endl; +#else + err() << "OpenGL ES extension EXT_sRGB unavailable" << std::endl; +#endif + err() << "Automatic sRGB to linear conversion disabled" << std::endl; + + warned = true; + } + + m_sRgb = false; + } + // Initialize the texture glCheck(glBindTexture(GL_TEXTURE_2D, m_texture)); - glCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_actualSize.x, m_actualSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL)); + glCheck(glTexImage2D(GL_TEXTURE_2D, 0, (m_sRgb ? GLEXT_GL_SRGB8_ALPHA8 : GL_RGBA), m_actualSize.x, m_actualSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL)); glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_isRepeated ? GL_REPEAT : (textureEdgeClamp ? GLEXT_GL_CLAMP_TO_EDGE : GLEXT_GL_CLAMP))); glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_isRepeated ? GL_REPEAT : (textureEdgeClamp ? GLEXT_GL_CLAMP_TO_EDGE : GLEXT_GL_CLAMP))); glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_isSmooth ? GL_LINEAR : GL_NEAREST)); glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_isSmooth ? GL_LINEAR : GL_NEAREST)); m_cacheId = getUniqueId(); + m_hasMipmap = false; + return true; } @@ -267,6 +302,9 @@ bool Texture::loadFromImage(const Image& image, const IntRect& area) pixels += 4 * width; } + glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_isSmooth ? GL_LINEAR : GL_NEAREST)); + m_hasMipmap = false; + // Force an OpenGL flush, so that the texture will appear updated // in all contexts immediately (solves problems in multi-threaded apps) glCheck(glFlush()); @@ -394,6 +432,8 @@ void Texture::update(const Uint8* pixels, unsigned int width, unsigned int heigh // Copy pixels from the given array to the texture glCheck(glBindTexture(GL_TEXTURE_2D, m_texture)); glCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels)); + glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_isSmooth ? GL_LINEAR : GL_NEAREST)); + m_hasMipmap = false; m_pixelsFlipped = false; m_cacheId = getUniqueId(); } @@ -436,6 +476,8 @@ void Texture::update(const Window& window, unsigned int x, unsigned int y) // Copy pixels from the back-buffer to the texture glCheck(glBindTexture(GL_TEXTURE_2D, m_texture)); glCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x, y, 0, 0, window.getSize().x, window.getSize().y)); + glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_isSmooth ? GL_LINEAR : GL_NEAREST)); + m_hasMipmap = false; m_pixelsFlipped = true; m_cacheId = getUniqueId(); } @@ -458,7 +500,15 @@ void Texture::setSmooth(bool smooth) glCheck(glBindTexture(GL_TEXTURE_2D, m_texture)); glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_isSmooth ? GL_LINEAR : GL_NEAREST)); - glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_isSmooth ? GL_LINEAR : GL_NEAREST)); + + if (m_hasMipmap) + { + glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_isSmooth ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_LINEAR)); + } + else + { + glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_isSmooth ? GL_LINEAR : GL_NEAREST)); + } } } } @@ -472,6 +522,20 @@ bool Texture::isSmooth() const //////////////////////////////////////////////////////////// +void Texture::setSrgb(bool sRgb) +{ + m_sRgb = sRgb; +} + + +//////////////////////////////////////////////////////////// +bool Texture::isSrgb() const +{ + return m_sRgb; +} + + +//////////////////////////////////////////////////////////// void Texture::setRepeated(bool repeated) { if (repeated != m_isRepeated) @@ -517,6 +581,51 @@ bool Texture::isRepeated() const //////////////////////////////////////////////////////////// +bool Texture::generateMipmap() +{ + if (!m_texture) + return false; + + ensureGlContext(); + + // Make sure that extensions are initialized + priv::ensureExtensionsInit(); + + if (!GLEXT_framebuffer_object) + return false; + + // Make sure that the current texture binding will be preserved + priv::TextureSaver save; + + glCheck(glBindTexture(GL_TEXTURE_2D, m_texture)); + glCheck(GLEXT_glGenerateMipmap(GL_TEXTURE_2D)); + glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_isSmooth ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_LINEAR)); + + m_hasMipmap = true; + + return true; +} + + +//////////////////////////////////////////////////////////// +void Texture::invalidateMipmap() +{ + if (!m_hasMipmap) + return; + + ensureGlContext(); + + // Make sure that the current texture binding will be preserved + priv::TextureSaver save; + + glCheck(glBindTexture(GL_TEXTURE_2D, m_texture)); + glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_isSmooth ? GL_LINEAR : GL_NEAREST)); + + m_hasMipmap = false; +} + + +//////////////////////////////////////////////////////////// void Texture::bind(const Texture* texture, CoordinateType coordinateType) { ensureGlContext(); @@ -596,6 +705,7 @@ Texture& Texture::operator =(const Texture& right) std::swap(m_isRepeated, temp.m_isRepeated); std::swap(m_pixelsFlipped, temp.m_pixelsFlipped); std::swap(m_fboAttachment, temp.m_fboAttachment); + std::swap(m_hasMipmap, temp.m_hasMipmap); m_cacheId = getUniqueId(); return *this; |