mirror of
https://github.com/love2d/love.git
synced 2026-08-16 08:11:02 +02:00
improved GL texture binding api to take texture units into consideration
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user