sf::Texture's function don't preserve the current texture binding anymore (was used to keep mixing SFML and OpenGL safe, but the potential performance loss was too high -- glGet* may trigger a glFlush)

This commit is contained in:
Laurent Gomila 2011-08-12 15:40:32 +02:00
parent ad42adbba0
commit 541509d2a7
4 changed files with 17 additions and 49 deletions

View File

@ -44,7 +44,7 @@ namespace priv
#ifdef SFML_DEBUG #ifdef SFML_DEBUG
// In debug mode, perform a test on every OpenGL call // In debug mode, perform a test on every OpenGL call
#define GLCheck(call) ((call), priv::GLCheckError(__FILE__, __LINE__)) #define GLCheck(call) ((call), sf::priv::GLCheckError(__FILE__, __LINE__))
#else #else

View File

@ -77,14 +77,9 @@ bool RenderTextureImplDefault::Activate(bool active)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void RenderTextureImplDefault::UpdateTexture(unsigned int textureId) void RenderTextureImplDefault::UpdateTexture(unsigned int textureId)
{ {
GLint previous;
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
// Copy the rendered pixels to the texture // Copy the rendered pixels to the texture
GLCheck(glBindTexture(GL_TEXTURE_2D, textureId)); GLCheck(glBindTexture(GL_TEXTURE_2D, textureId));
GLCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, myWidth, myHeight)); GLCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, myWidth, myHeight));
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
} }
} // namespace priv } // namespace priv

View File

@ -34,6 +34,21 @@
#include <vector> #include <vector>
////////////////////////////////////////////////////////////
// Private data
////////////////////////////////////////////////////////////
namespace
{
// Retrieve the maximum number of texture units available
GLint GetMaxTextureUnits()
{
GLint maxUnits;
GLCheck(glGetIntegerv(GL_MAX_TEXTURE_COORDS_ARB, &maxUnits));
return maxUnits;
}
}
namespace sf namespace sf
{ {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -244,8 +259,7 @@ void Shader::SetTexture(const std::string& name, const Texture& texture)
if (it == myTextures.end()) if (it == myTextures.end())
{ {
// New entry, make sure there are enough texture units // New entry, make sure there are enough texture units
GLint maxUnits; static const GLint maxUnits = GetMaxTextureUnits();
GLCheck(glGetIntegerv(GL_MAX_TEXTURE_COORDS_ARB, &maxUnits));
if (myTextures.size() + 1 >= static_cast<std::size_t>(maxUnits)) if (myTextures.size() + 1 >= static_cast<std::size_t>(maxUnits))
{ {
Err() << "Impossible to use texture \"" << name << "\" for shader: all available texture units are used" << std::endl; Err() << "Impossible to use texture \"" << name << "\" for shader: all available texture units are used" << std::endl;

View File

@ -121,10 +121,6 @@ bool Texture::Create(unsigned int width, unsigned int height)
myTexture = static_cast<unsigned int>(texture); myTexture = static_cast<unsigned int>(texture);
} }
// Save the current texture binding
GLint previous;
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
// Initialize the texture // Initialize the texture
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture)); GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
GLCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, myTextureWidth, myTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL)); GLCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, myTextureWidth, myTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL));
@ -133,9 +129,6 @@ bool Texture::Create(unsigned int width, unsigned int height)
GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myIsSmooth ? GL_LINEAR : GL_NEAREST)); GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myIsSmooth ? GL_LINEAR : GL_NEAREST));
GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myIsSmooth ? GL_LINEAR : GL_NEAREST)); GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myIsSmooth ? GL_LINEAR : GL_NEAREST));
// Restore the previous texture
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
return true; return true;
} }
@ -200,10 +193,6 @@ bool Texture::LoadFromImage(const Image& image, const IntRect& area)
// Create the texture and upload the pixels // Create the texture and upload the pixels
if (Create(rectangle.Width, rectangle.Height)) if (Create(rectangle.Width, rectangle.Height))
{ {
// Save the current texture binding
GLint previous;
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
// Copy the pixels to the texture, row by row // Copy the pixels to the texture, row by row
const Uint8* pixels = image.GetPixelsPtr() + rectangle.Left + (width * rectangle.Top); const Uint8* pixels = image.GetPixelsPtr() + rectangle.Left + (width * rectangle.Top);
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture)); GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
@ -212,10 +201,6 @@ bool Texture::LoadFromImage(const Image& image, const IntRect& area)
GLCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, i, myWidth, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels)); GLCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, i, myWidth, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
pixels += width; pixels += width;
} }
myPixelsFlipped = false;
// Restore the previous texture
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
return true; return true;
} }
@ -250,10 +235,6 @@ Image Texture::CopyToImage() const
EnsureGlContext(); EnsureGlContext();
// Save the previous texture
GLint previous;
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
// Create an array of pixels // Create an array of pixels
std::vector<Uint8> pixels(myWidth * myHeight * 4); std::vector<Uint8> pixels(myWidth * myHeight * 4);
@ -293,9 +274,6 @@ Image Texture::CopyToImage() const
} }
} }
// Restore the previous texture
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
// Create the image // Create the image
Image image; Image image;
image.Create(myWidth, myHeight, &pixels[0]); image.Create(myWidth, myHeight, &pixels[0]);
@ -322,17 +300,10 @@ void Texture::Update(const Uint8* pixels, unsigned int width, unsigned int heigh
{ {
EnsureGlContext(); EnsureGlContext();
// Save the current texture binding
GLint previous;
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
// Copy pixels from the given array to the texture // Copy pixels from the given array to the texture
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture)); GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
GLCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels)); GLCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
myPixelsFlipped = false; myPixelsFlipped = false;
// Restore the previous texture
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
} }
} }
@ -367,17 +338,10 @@ void Texture::Update(const Window& window, unsigned int x, unsigned int y)
if (myTexture && window.SetActive(true)) if (myTexture && window.SetActive(true))
{ {
// Save the current texture binding
GLint previous;
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
// Copy pixels from the back-buffer to the texture // Copy pixels from the back-buffer to the texture
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture)); GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
GLCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x, y, 0, 0, window.GetWidth(), window.GetHeight())); GLCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x, y, 0, 0, window.GetWidth(), window.GetHeight()));
myPixelsFlipped = true; myPixelsFlipped = true;
// Restore the previous texture
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
} }
} }
@ -400,14 +364,9 @@ void Texture::SetSmooth(bool smooth)
{ {
EnsureGlContext(); EnsureGlContext();
GLint previous;
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture)); GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myIsSmooth ? GL_LINEAR : GL_NEAREST)); GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myIsSmooth ? GL_LINEAR : GL_NEAREST));
GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myIsSmooth ? GL_LINEAR : GL_NEAREST)); GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myIsSmooth ? GL_LINEAR : GL_NEAREST));
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
} }
} }
} }