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)
{
currentWindow = love::window::sdl::Window::getSingleton();
resetBoundTexture();
}
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
// the display mode change.
Volatile::unloadAll();
uninitializeContext();
bool success = currentWindow->setWindow(width, height, fullscreen, vsync, fsaa);
// 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();
// Okay, setup OpenGL.
initializeContext();
// Enable blending
glEnable(GL_BLEND);
@@ -138,6 +140,7 @@ bool Graphics::setMode(int width, int height, bool fullscreen, bool vsync, int f
// Enable textures
glEnable(GL_TEXTURE_2D);
setActiveTextureUnit(GL_TEXTURE0);
// Set the viewport to top-left corner
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.
**/
#include <vector>
#include "OpenGL.h"
#include "common/Exception.h"
namespace love
{
@@ -27,27 +29,95 @@ namespace graphics
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
boundTexture = 0;
if (contextInitialized)
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);
}
}
void deleteTexture(GLuint texture)
{
if (texture == boundTexture)
boundTexture = 0;
initializeContext();
std::vector<GLuint>::iterator it;
for (it = textureUnits.begin(); it != textureUnits.end(); ++it)
{
if (*it == texture)
*it = 0;
}
glDeleteTextures(1, &texture);
}
+10 -4
View File
@@ -30,16 +30,22 @@ namespace graphics
namespace opengl
{
// resets the stored bound texture id
void resetBoundTexture();
void initializeContext();
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.
* Makes sure we aren't redundantly binding textures.
* @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.
+3 -3
View File
@@ -332,12 +332,12 @@ void ShaderEffect::sendTexture(const std::string &name, GLuint texture)
GLint texture_unit = getTextureUnit(name);
glActiveTexture(GL_TEXTURE0 + texture_unit);
bindTexture(texture, true); // guarantee it gets bound
setActiveTextureUnit(GL_TEXTURE0 + texture_unit);
bindTexture(texture);
glUniform1i(location, texture_unit);
// reset texture unit
glActiveTexture(GL_TEXTURE0);
setActiveTextureUnit(GL_TEXTURE0);
// throw error if needed
checkSetUniformError();
@@ -48,6 +48,7 @@ public:
void attach();
static void detach();
static std::string getGLSLVersion();
static bool isSupported();