summaryrefslogtreecommitdiff
path: root/src/SFML/Graphics/Texture.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/SFML/Graphics/Texture.cpp')
-rw-r--r--src/SFML/Graphics/Texture.cpp118
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;