Minor modifications to shader and image activation

git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1426 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
LaurentGom 2010-02-25 12:37:51 +00:00
parent 341b499180
commit 76a76a784f
3 changed files with 61 additions and 74 deletions

View File

@ -493,11 +493,7 @@ void Image::Bind() const
EnsureTextureUpdate(); EnsureTextureUpdate();
// Bind it // Bind it
if (myTexture) GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
{
GLCheck(glEnable(GL_TEXTURE_2D));
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
}
} }

View File

@ -58,6 +58,7 @@ void Renderer::Initialize()
// Default render states // Default render states
GLCheck(glDisable(GL_LIGHTING)); GLCheck(glDisable(GL_LIGHTING));
GLCheck(glDisable(GL_DEPTH_TEST)); GLCheck(glDisable(GL_DEPTH_TEST));
GLCheck(glEnable(GL_TEXTURE_2D));
GLCheck(glEnable(GL_ALPHA_TEST)); GLCheck(glEnable(GL_ALPHA_TEST));
GLCheck(glAlphaFunc(GL_GREATER, 0)); GLCheck(glAlphaFunc(GL_GREATER, 0));
@ -241,7 +242,7 @@ void Renderer::SetTexture(const Image* texture)
if (texture) if (texture)
texture->Bind(); texture->Bind();
else else
GLCheck(glDisable(GL_TEXTURE_2D)); GLCheck(glBindTexture(GL_TEXTURE_2D, 0));
// Store it // Store it
myTexture = texture; myTexture = texture;
@ -255,15 +256,18 @@ void Renderer::SetShader(const Shader* shader)
{ {
if ((shader != myShader) || !myShaderIsValid) if ((shader != myShader) || !myShaderIsValid)
{ {
// Apply the new shader if (Shader::IsAvailable()) // to avoid calling possibly unsupported functions
if (shader) {
shader->Bind(); // Apply the new shader
else if (myShaderIsValid && myShader) if (shader)
myShader->Unbind(); shader->Bind();
else
GLCheck(glUseProgramObjectARB(0));
// Store it // Store it
myShader = shader; myShader = shader;
myShaderIsValid = true; myShaderIsValid = true;
}
} }
} }

View File

@ -45,8 +45,7 @@ Shader::Shader() :
myShaderProgram (0), myShaderProgram (0),
myCurrentTexture(-1) myCurrentTexture(-1)
{ {
// Make sure that GLEW is initialized
priv::EnsureGlewInit();
} }
@ -209,82 +208,67 @@ void Shader::SetParameter(const std::string& name, const Vector3f& v)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Shader::SetTexture(const std::string& name, const Image& texture) void Shader::SetTexture(const std::string& name, const Image& texture)
{ {
// Check if there is a texture unit available if (myShaderProgram)
GLint maxUnits;
GLCheck(glGetIntegerv(GL_MAX_TEXTURE_COORDS_ARB, &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; // Check if there is a texture unit available
return; GLint maxUnits;
} GLCheck(glGetIntegerv(GL_MAX_TEXTURE_COORDS_ARB, &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;
return;
}
// Make sure the given name is a valid variable in the effect // Make sure the given name is a valid variable in the effect
int location = glGetUniformLocationARB(myShaderProgram, name.c_str()); int location = glGetUniformLocationARB(myShaderProgram, name.c_str());
if (location == -1) if (location == -1)
{ {
Err() << "Texture \"" << name << "\" not found in shader" << std::endl; Err() << "Texture \"" << name << "\" not found in shader" << std::endl;
return; return;
} }
// Store the texture for later use // Store the texture for later use
if (&texture != &CurrentTexture) if (&texture != &CurrentTexture)
myTextures[location] = &texture; myTextures[location] = &texture;
else else
myCurrentTexture = location; myCurrentTexture = location;
}
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Shader::Bind() const void Shader::Bind() const
{ {
// Make sure that we have a valid program if (myShaderProgram)
if (!myShaderProgram)
return;
// Enable the program
GLCheck(glUseProgramObjectARB(myShaderProgram));
// Bind the textures
TextureTable::const_iterator it = myTextures.begin();
for (std::size_t i = 0; i < myTextures.size(); ++i)
{ {
GLint index = static_cast<GLsizei>(i + 1); // Enable the program
GLCheck(glUniform1iARB(it->first, index)); GLCheck(glUseProgramObjectARB(myShaderProgram));
GLCheck(glActiveTextureARB(GL_TEXTURE0_ARB + index));
it->second->Bind(); // Bind the textures
it++; TextureTable::const_iterator it = myTextures.begin();
for (std::size_t i = 0; i < myTextures.size(); ++i)
{
GLint index = static_cast<GLsizei>(i + 1);
GLCheck(glUniform1iARB(it->first, index));
GLCheck(glActiveTextureARB(GL_TEXTURE0_ARB + index));
it->second->Bind();
it++;
}
// Make sure that the texture unit which is left active is the number 0
GLCheck(glActiveTextureARB(GL_TEXTURE0_ARB));
// Bind the current texture
if (myCurrentTexture != -1)
GLCheck(glUniform1iARB(myCurrentTexture, 0));
} }
// Make sure that the texture unit which is left active is the number 0
GLCheck(glActiveTextureARB(GL_TEXTURE0_ARB));
// Bind the current texture
if (myCurrentTexture != -1)
GLCheck(glUniform1iARB(myCurrentTexture, 0));
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Shader::Unbind() const void Shader::Unbind() const
{ {
// First make sure that the program is currently bound
GLhandleARB program = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
if (!myShaderProgram || (myShaderProgram != program))
return;
// Unbind the program
GLCheck(glUseProgramObjectARB(0)); GLCheck(glUseProgramObjectARB(0));
// Disable texture units
for (std::size_t i = 0; i < myTextures.size(); ++i)
{
GLint index = static_cast<GLsizei>(i + 1);
GLCheck(glActiveTextureARB(GL_TEXTURE0_ARB + index));
GLCheck(glBindTexture(GL_TEXTURE_2D, 0));
}
// Make sure that the texture unit which is left active is the number 0
GLCheck(glActiveTextureARB(GL_TEXTURE0_ARB));
} }
@ -326,6 +310,9 @@ bool Shader::CompileProgram()
return false; return false;
} }
// Make sure that GLEW is initialized (extra safety -- it is already done in IsAvailable())
priv::EnsureGlewInit();
// Destroy the shader if it was already created // Destroy the shader if it was already created
if (myShaderProgram) if (myShaderProgram)
GLCheck(glDeleteObjectARB(myShaderProgram)); GLCheck(glDeleteObjectARB(myShaderProgram));