improved GL texture binding api to take texture units into consideration

This commit is contained in:
Alexander Szpakowski
2012-12-21 20:35:32 -04:00
parent 5626b74b79
commit 16f925affa
5 changed files with 98 additions and 18 deletions
+5 -2
View File
@@ -45,8 +45,6 @@ Graphics::Graphics()
, userMatrices(0) , userMatrices(0)
{ {
currentWindow = love::window::sdl::Window::getSingleton(); currentWindow = love::window::sdl::Window::getSingleton();
resetBoundTexture();
} }
Graphics::~Graphics() Graphics::~Graphics()
@@ -116,6 +114,8 @@ bool Graphics::setMode(int width, int height, bool fullscreen, bool vsync, int f
// Unload all volatile objects. These must be reloaded after // Unload all volatile objects. These must be reloaded after
// the display mode change. // the display mode change.
Volatile::unloadAll(); Volatile::unloadAll();
uninitializeContext();
bool success = currentWindow->setWindow(width, height, fullscreen, vsync, fsaa); bool success = currentWindow->setWindow(width, height, fullscreen, vsync, fsaa);
// Regardless of failure, we'll have to set up OpenGL once again. // Regardless of failure, we'll have to set up OpenGL once again.
@@ -124,6 +124,8 @@ bool Graphics::setMode(int width, int height, bool fullscreen, bool vsync, int f
height = currentWindow->getHeight(); height = currentWindow->getHeight();
// Okay, setup OpenGL. // Okay, setup OpenGL.
initializeContext();
// Enable blending // Enable blending
glEnable(GL_BLEND); glEnable(GL_BLEND);
@@ -138,6 +140,7 @@ bool Graphics::setMode(int width, int height, bool fullscreen, bool vsync, int f
// Enable textures // Enable textures
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
setActiveTextureUnit(GL_TEXTURE0);
// Set the viewport to top-left corner // Set the viewport to top-left corner
glViewport(0, 0, width, height); glViewport(0, 0, width, height);
+79 -9
View File
@@ -18,7 +18,9 @@
* 3. This notice may not be removed or altered from any source distribution. * 3. This notice may not be removed or altered from any source distribution.
**/ **/
#include <vector>
#include "OpenGL.h" #include "OpenGL.h"
#include "common/Exception.h"
namespace love namespace love
{ {
@@ -27,27 +29,95 @@ namespace graphics
namespace opengl namespace opengl
{ {
static GLuint boundTexture = 0; static bool contextInitialized = false;
void resetBoundTexture() static int curTextureUnitIndex = 0;
static std::vector<GLuint> textureUnits;
void initializeContext()
{ {
// OpenGL might not be initialized yet, so we can't do a real reset if (contextInitialized)
boundTexture = 0; return;
contextInitialized = true;
if (GLEE_ARB_multitexture || GLEE_VERSION_1_3)
{
GLint maxtextureunits;
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &maxtextureunits);
if (GLEE_VERSION_2_0 || GLEE_ARB_vertex_shader)
{
GLint maxtextureimageunits;
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxtextureimageunits);
if (maxtextureimageunits > maxtextureunits)
maxtextureunits = maxtextureimageunits;
}
textureUnits.resize(maxtextureunits, 0);
GLenum activeTextureUnit;
glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint *)&activeTextureUnit);
curTextureUnitIndex = activeTextureUnit - GL_TEXTURE0;
}
else
{
// multitexturing not supported so we only have 1 texture unit
textureUnits.resize(1, 0);
curTextureUnitIndex = 0;
}
} }
void bindTexture(GLuint texture, bool override) void uninitializeContext()
{ {
if (texture != boundTexture || texture == 0 || override) contextInitialized = false;
}
void setActiveTextureUnit(GLenum textureunit)
{
initializeContext();
int textureunitindex = textureunit - GL_TEXTURE0;
if (textureunitindex < 0 || (size_t) textureunitindex >= textureUnits.size())
throw love::Exception("Invalid texture unit index.");
if (textureunitindex != curTextureUnitIndex)
{ {
boundTexture = texture; if (GLEE_VERSION_1_3)
glActiveTexture(textureunit);
else if (GLEE_ARB_multitexture)
glActiveTextureARB(textureunit);
else
throw love::Exception("Multitexturing not supported.");
}
curTextureUnitIndex = textureunitindex;
}
void bindTexture(GLuint texture)
{
initializeContext();
if (texture != textureUnits[curTextureUnitIndex] || texture == 0)
{
textureUnits[curTextureUnitIndex] = texture;
glBindTexture(GL_TEXTURE_2D, texture); glBindTexture(GL_TEXTURE_2D, texture);
} }
} }
void deleteTexture(GLuint texture) void deleteTexture(GLuint texture)
{ {
if (texture == boundTexture) initializeContext();
boundTexture = 0;
std::vector<GLuint>::iterator it;
for (it = textureUnits.begin(); it != textureUnits.end(); ++it)
{
if (*it == texture)
*it = 0;
}
glDeleteTextures(1, &texture); glDeleteTextures(1, &texture);
} }
+10 -4
View File
@@ -30,16 +30,22 @@ namespace graphics
namespace opengl namespace opengl
{ {
// resets the stored bound texture id void initializeContext();
void resetBoundTexture();
void uninitializeContext();
/**
* Helper for setting the active texture unit
* @param textureunit The GL texture unit to set
**/
void setActiveTextureUnit(GLenum textureunit);
/** /**
* Helper for binding an OpenGL texture. * Helper for binding an OpenGL texture.
* Makes sure we aren't redundantly binding textures. * Makes sure we aren't redundantly binding textures.
* @param texture The texture to bind. * @param texture The texture to bind.
* @param override Overrides the checks to guarantee texture bind
**/ **/
void bindTexture(GLuint texture, bool override = false); void bindTexture(GLuint texture);
/** /**
* Helper for deleting an OpenGL texture. * Helper for deleting an OpenGL texture.
+3 -3
View File
@@ -332,12 +332,12 @@ void ShaderEffect::sendTexture(const std::string &name, GLuint texture)
GLint texture_unit = getTextureUnit(name); GLint texture_unit = getTextureUnit(name);
glActiveTexture(GL_TEXTURE0 + texture_unit); setActiveTextureUnit(GL_TEXTURE0 + texture_unit);
bindTexture(texture, true); // guarantee it gets bound bindTexture(texture);
glUniform1i(location, texture_unit); glUniform1i(location, texture_unit);
// reset texture unit // reset texture unit
glActiveTexture(GL_TEXTURE0); setActiveTextureUnit(GL_TEXTURE0);
// throw error if needed // throw error if needed
checkSetUniformError(); checkSetUniformError();
@@ -48,6 +48,7 @@ public:
void attach(); void attach();
static void detach(); static void detach();
static std::string getGLSLVersion(); static std::string getGLSLVersion();
static bool isSupported(); static bool isSupported();