Merge branch 'bugfix/texture_max_size'

This commit is contained in:
Lukas Dürrenberger 2014-08-19 22:18:38 +02:00
commit 7c63c5885e
7 changed files with 81 additions and 40 deletions

View File

@ -22,9 +22,6 @@ int main()
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML graphics with OpenGL", sf::Style::Default, contextSettings); sf::RenderWindow window(sf::VideoMode(800, 600), "SFML graphics with OpenGL", sf::Style::Default, contextSettings);
window.setVerticalSyncEnabled(true); window.setVerticalSyncEnabled(true);
// Make it the active window for OpenGL calls
window.setActive();
// Create a sprite for the background // Create a sprite for the background
sf::Texture backgroundTexture; sf::Texture backgroundTexture;
if (!backgroundTexture.loadFromFile("resources/background.jpg")) if (!backgroundTexture.loadFromFile("resources/background.jpg"))
@ -39,6 +36,13 @@ int main()
text.setColor(sf::Color(255, 255, 255, 170)); text.setColor(sf::Color(255, 255, 255, 170));
text.setPosition(250.f, 450.f); text.setPosition(250.f, 450.f);
// Make the window the active target for OpenGL calls
// Note: If using sf::Texture or sf::Shader with OpenGL,
// be sure to call sf::Texture::getMaximumSize() and/or
// sf::Shader::isAvailable() at least once before calling
// setActive(), as those functions will cause a context switch
window.setActive();
// Load an OpenGL texture. // Load an OpenGL texture.
// We could directly use a sf::Texture as an OpenGL texture (with its Bind() member function), // We could directly use a sf::Texture as an OpenGL texture (with its Bind() member function),
// but here we want more control on it (generate mipmaps, ...) so we create a new one from an image // but here we want more control on it (generate mipmaps, ...) so we create a new one from an image

View File

@ -486,6 +486,9 @@ public :
/// the shader features. If it returns false, then /// the shader features. If it returns false, then
/// any attempt to use sf::Shader will fail. /// any attempt to use sf::Shader will fail.
/// ///
/// Note: The first call to this function, whether by your
/// code or SFML will result in a context switch.
///
/// \return True if shaders are supported, false otherwise /// \return True if shaders are supported, false otherwise
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -460,6 +460,9 @@ public :
/// You can expect a value of 512 pixels for low-end graphics /// You can expect a value of 512 pixels for low-end graphics
/// card, and up to 8192 pixels or more for newer hardware. /// card, and up to 8192 pixels or more for newer hardware.
/// ///
/// Note: The first call to this function, whether by your
/// code or SFML will result in a context switch.
///
/// \return Maximum size allowed for textures, in pixels /// \return Maximum size allowed for textures, in pixels
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -31,6 +31,8 @@
#include <SFML/Graphics/GLCheck.hpp> #include <SFML/Graphics/GLCheck.hpp>
#include <SFML/Window/Context.hpp> #include <SFML/Window/Context.hpp>
#include <SFML/System/InputStream.hpp> #include <SFML/System/InputStream.hpp>
#include <SFML/System/Mutex.hpp>
#include <SFML/System/Lock.hpp>
#include <SFML/System/Err.hpp> #include <SFML/System/Err.hpp>
#include <fstream> #include <fstream>
#include <vector> #include <vector>
@ -40,11 +42,25 @@
namespace namespace
{ {
sf::Mutex mutex;
GLint checkMaxTextureUnits()
{
GLint maxUnits = 0;
glCheck(glGetIntegerv(GL_MAX_TEXTURE_COORDS_ARB, &maxUnits));
return maxUnits;
}
// Retrieve the maximum number of texture units available // Retrieve the maximum number of texture units available
GLint getMaxTextureUnits() GLint getMaxTextureUnits()
{ {
GLint maxUnits = 0; // TODO: Remove this lock when it becomes unnecessary in C++11
glCheck(glGetIntegerv(GL_MAX_TEXTURE_COORDS_ARB, &maxUnits)); sf::Lock lock(mutex);
static GLint maxUnits = checkMaxTextureUnits();
return maxUnits; return maxUnits;
} }
@ -86,6 +102,24 @@ namespace
buffer.push_back('\0'); buffer.push_back('\0');
return success; return success;
} }
bool checkShadersAvailable()
{
// Create a temporary context in case the user checks
// before a GlResource is created, thus initializing
// the shared context
sf::Context context;
// Make sure that extensions are initialized
sf::priv::ensureExtensionsInit();
bool available = GLEW_ARB_shading_language_100 &&
GLEW_ARB_shader_objects &&
GLEW_ARB_vertex_shader &&
GLEW_ARB_fragment_shader;
return available;
}
} }
@ -378,7 +412,7 @@ void Shader::setParameter(const std::string& name, const Texture& texture)
if (it == m_textures.end()) if (it == m_textures.end())
{ {
// New entry, make sure there are enough texture units // New entry, make sure there are enough texture units
static const GLint maxUnits = getMaxTextureUnits(); GLint maxUnits = getMaxTextureUnits();
if (m_textures.size() + 1 >= static_cast<std::size_t>(maxUnits)) if (m_textures.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;
@ -438,27 +472,10 @@ void Shader::bind(const Shader* shader)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool Shader::isAvailable() bool Shader::isAvailable()
{ {
static bool available = false; // TODO: Remove this lock when it becomes unnecessary in C++11
static bool checked = false; Lock lock(mutex);
// Make sure we only have to check once static bool available = checkShadersAvailable();
if (!checked)
{
// Create a temporary context in case the user checks
// before a GlResource is created, thus initializing
// the shared context
Context context;
// Make sure that extensions are initialized
priv::ensureExtensionsInit();
available = GLEW_ARB_shading_language_100 &&
GLEW_ARB_shader_objects &&
GLEW_ARB_vertex_shader &&
GLEW_ARB_fragment_shader;
checked = true;
}
return available; return available;
} }

View File

@ -28,7 +28,6 @@
#include <SFML/Graphics/Text.hpp> #include <SFML/Graphics/Text.hpp>
#include <SFML/Graphics/Texture.hpp> #include <SFML/Graphics/Texture.hpp>
#include <SFML/Graphics/RenderTarget.hpp> #include <SFML/Graphics/RenderTarget.hpp>
#include <cassert>
namespace sf namespace sf

View File

@ -29,6 +29,7 @@
#include <SFML/Graphics/Image.hpp> #include <SFML/Graphics/Image.hpp>
#include <SFML/Graphics/GLCheck.hpp> #include <SFML/Graphics/GLCheck.hpp>
#include <SFML/Graphics/TextureSaver.hpp> #include <SFML/Graphics/TextureSaver.hpp>
#include <SFML/Window/Context.hpp>
#include <SFML/Window/Window.hpp> #include <SFML/Window/Window.hpp>
#include <SFML/System/Mutex.hpp> #include <SFML/System/Mutex.hpp>
#include <SFML/System/Lock.hpp> #include <SFML/System/Lock.hpp>
@ -39,16 +40,31 @@
namespace namespace
{ {
sf::Mutex mutex;
// Thread-safe unique identifier generator, // Thread-safe unique identifier generator,
// is used for states cache (see RenderTarget) // is used for states cache (see RenderTarget)
sf::Uint64 getUniqueId() sf::Uint64 getUniqueId()
{ {
static sf::Uint64 id = 1; // start at 1, zero is "no texture"
static sf::Mutex mutex;
sf::Lock lock(mutex); sf::Lock lock(mutex);
static sf::Uint64 id = 1; // start at 1, zero is "no texture"
return id++; return id++;
} }
unsigned int checkMaximumTextureSize()
{
// Create a temporary context in case the user queries
// the size before a GlResource is created, thus
// initializing the shared context
sf::Context context;
GLint size;
glCheck(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size));
return static_cast<unsigned int>(size);
}
} }
@ -522,12 +538,12 @@ void Texture::bind(const Texture* texture, CoordinateType coordinateType)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
unsigned int Texture::getMaximumSize() unsigned int Texture::getMaximumSize()
{ {
ensureGlContext(); // TODO: Remove this lock when it becomes unnecessary in C++11
Lock lock(mutex);
GLint size; static unsigned int size = checkMaximumTextureSize();
glCheck(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size));
return static_cast<unsigned int>(size); return size;
} }

View File

@ -32,7 +32,6 @@
#include <SFML/OpenGL.hpp> #include <SFML/OpenGL.hpp>
#include <set> #include <set>
#include <cstdlib> #include <cstdlib>
#include <cassert>
#ifdef SFML_SYSTEM_IOS #ifdef SFML_SYSTEM_IOS
#include <OpenGLES/ES1/gl.h> #include <OpenGLES/ES1/gl.h>
#else #else