mirror of
https://github.com/love2d/love.git
synced 2026-08-17 19:23:38 +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)
|
, userMatrices(0)
|
||||||
{
|
{
|
||||||
currentWindow = love::window::sdl::Window::getSingleton();
|
currentWindow = love::window::sdl::Window::getSingleton();
|
||||||
|
|
||||||
resetBoundTexture();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Graphics::~Graphics()
|
Graphics::~Graphics()
|
||||||
@@ -117,6 +115,8 @@ bool Graphics::setMode(int width, int height, bool fullscreen, bool vsync, int f
|
|||||||
// 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.
|
||||||
|
|
||||||
@@ -125,6 +125,8 @@ bool Graphics::setMode(int width, int height, bool fullscreen, bool vsync, int f
|
|||||||
|
|
||||||
// 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);
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user