mirror of
https://github.com/love2d/love.git
synced 2026-08-17 19:23:38 +02:00
Fix #756: Sending an Image to a shader does not retain it
Each shader contains a map of uniform name -> bound retainable Object. After setting the uniform, sendImage() and sendCanvas() release() the Object with the requested name (if present) and record the new Image/Canvas. Related bugfix: Shader::attach() calls retain()/release() on the shader.
This commit is contained in:
@@ -91,6 +91,12 @@ Shader::~Shader()
|
|||||||
if (current == this)
|
if (current == this)
|
||||||
detach();
|
detach();
|
||||||
|
|
||||||
|
for (auto it = boundRetainables.begin(); it != boundRetainables.end(); ++it)
|
||||||
|
{
|
||||||
|
it->second->release();
|
||||||
|
boundRetainables.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
unloadVolatile();
|
unloadVolatile();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,8 +337,13 @@ void Shader::attach(bool temporary)
|
|||||||
{
|
{
|
||||||
if (current != this)
|
if (current != this)
|
||||||
{
|
{
|
||||||
|
if (current != NULL)
|
||||||
|
current->release();
|
||||||
|
|
||||||
glUseProgram(program);
|
glUseProgram(program);
|
||||||
current = this;
|
current = this;
|
||||||
|
|
||||||
|
current->retain();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!temporary)
|
if (!temporary)
|
||||||
@@ -558,14 +569,26 @@ void Shader::sendTexture(const std::string &name, GLuint texture)
|
|||||||
activeTextureUnits[textureunit-1] = texture;
|
activeTextureUnits[textureunit-1] = texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shader::sendImage(const std::string &name, const Image &image)
|
void Shader::retainTexture(const std::string &name, Object *texture)
|
||||||
{
|
{
|
||||||
sendTexture(name, image.getTextureName());
|
auto it = boundRetainables.find(name);
|
||||||
|
if (it != boundRetainables.end())
|
||||||
|
it->second->release();
|
||||||
|
|
||||||
|
texture->retain();
|
||||||
|
boundRetainables[name] = texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shader::sendCanvas(const std::string &name, const Canvas &canvas)
|
void Shader::sendImage(const std::string &name, Image &image)
|
||||||
|
{
|
||||||
|
sendTexture(name, image.getTextureName());
|
||||||
|
retainTexture(name, &image);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::sendCanvas(const std::string &name, Canvas &canvas)
|
||||||
{
|
{
|
||||||
sendTexture(name, canvas.getTextureName());
|
sendTexture(name, canvas.getTextureName());
|
||||||
|
retainTexture(name, &canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Shader::getTextureUnit(const std::string &name)
|
int Shader::getTextureUnit(const std::string &name)
|
||||||
|
|||||||
@@ -124,14 +124,14 @@ public:
|
|||||||
*
|
*
|
||||||
* @param name The name of the uniform variable in the source code.
|
* @param name The name of the uniform variable in the source code.
|
||||||
**/
|
**/
|
||||||
void sendImage(const std::string &name, const Image &image);
|
void sendImage(const std::string &name, Image &image);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a canvas to this Shader as a uniform.
|
* Send a canvas to this Shader as a uniform.
|
||||||
*
|
*
|
||||||
* @param name The name of the uniform variable in the source code.
|
* @param name The name of the uniform variable in the source code.
|
||||||
**/
|
**/
|
||||||
void sendCanvas(const std::string &name, const Canvas &canvas);
|
void sendCanvas(const std::string &name, Canvas &canvas);
|
||||||
|
|
||||||
static std::string getGLSLVersion();
|
static std::string getGLSLVersion();
|
||||||
static bool isSupported();
|
static bool isSupported();
|
||||||
@@ -173,6 +173,7 @@ private:
|
|||||||
int getTextureUnit(const std::string &name);
|
int getTextureUnit(const std::string &name);
|
||||||
|
|
||||||
void sendTexture(const std::string &name, GLuint texture);
|
void sendTexture(const std::string &name, GLuint texture);
|
||||||
|
void retainTexture(const std::string &name, Object *texture);
|
||||||
|
|
||||||
// Get any warnings or errors generated only by the shader program object.
|
// Get any warnings or errors generated only by the shader program object.
|
||||||
std::string getProgramWarnings() const;
|
std::string getProgramWarnings() const;
|
||||||
@@ -193,6 +194,9 @@ private:
|
|||||||
std::map<std::string, GLint> textureUnitPool; // textureUnitPool[name] = textureunit
|
std::map<std::string, GLint> textureUnitPool; // textureUnitPool[name] = textureunit
|
||||||
std::vector<GLuint> activeTextureUnits; // activeTextureUnits[textureunit-1] = textureid
|
std::vector<GLuint> activeTextureUnits; // activeTextureUnits[textureunit-1] = textureid
|
||||||
|
|
||||||
|
// Uniform name to retainable objects
|
||||||
|
std::map<std::string, Object*> boundRetainables;
|
||||||
|
|
||||||
// Max GPU texture units available for sent images
|
// Max GPU texture units available for sent images
|
||||||
static GLint maxTextureUnits;
|
static GLint maxTextureUnits;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user