mirror of https://github.com/axmolengine/axmol.git
fixed #16871: Material second shader texture will be lost when removeUnusedTextures is invoked. (#16884)
* fixed #16871: Material second shader texture will be lost when removeUnusedTextures is invoked. * issue #16871: Adds test case for issue #16871. * issue #16871: Checks whether current texture is the same as which is passed in. And more comments for release stuffs. * Removes unused nullptr check of _value.tex.texture CC_SAFE_RETAIN will check it. And some indention fixes.
This commit is contained in:
parent
34d4c65c86
commit
27e2012cf1
|
@ -65,10 +65,20 @@ UniformValue::UniformValue(Uniform *uniform, GLProgram* glprogram)
|
|||
{
|
||||
}
|
||||
|
||||
UniformValue::UniformValue(const UniformValue& o)
|
||||
{
|
||||
*this = o;
|
||||
}
|
||||
|
||||
UniformValue::~UniformValue()
|
||||
{
|
||||
if (_type == Type::CALLBACK_FN)
|
||||
delete _value.callback;
|
||||
if (_type == Type::CALLBACK_FN)
|
||||
delete _value.callback;
|
||||
|
||||
if (_uniform->type == GL_SAMPLER_2D)
|
||||
{
|
||||
CC_SAFE_RELEASE(_value.tex.texture);
|
||||
}
|
||||
}
|
||||
|
||||
void UniformValue::apply()
|
||||
|
@ -147,12 +157,12 @@ void UniformValue::apply()
|
|||
|
||||
void UniformValue::setCallback(const std::function<void(GLProgram*, Uniform*)> &callback)
|
||||
{
|
||||
// delete previously set callback
|
||||
// TODO: memory will leak if the user does:
|
||||
// value->setCallback();
|
||||
// value->setFloat();
|
||||
// delete previously set callback
|
||||
// TODO: memory will leak if the user does:
|
||||
// value->setCallback();
|
||||
// value->setFloat();
|
||||
if (_type == Type::CALLBACK_FN)
|
||||
delete _value.callback;
|
||||
delete _value.callback;
|
||||
|
||||
_value.callback = new (std::nothrow) std::function<void(GLProgram*, Uniform*)>();
|
||||
*_value.callback = callback;
|
||||
|
@ -165,8 +175,26 @@ void UniformValue::setTexture(GLuint textureId, GLuint textureUnit)
|
|||
//CCASSERT(_uniform->type == GL_SAMPLER_2D, "Wrong type. expecting GL_SAMPLER_2D");
|
||||
_value.tex.textureId = textureId;
|
||||
_value.tex.textureUnit = textureUnit;
|
||||
_value.tex.texture = nullptr;
|
||||
_type = Type::VALUE;
|
||||
}
|
||||
|
||||
void UniformValue::setTexture(Texture2D* texture, GLuint textureUnit)
|
||||
{
|
||||
CCASSERT(texture != nullptr, "texture is nullptr");
|
||||
|
||||
if (texture != _value.tex.texture)
|
||||
{
|
||||
CC_SAFE_RELEASE(_value.tex.texture);
|
||||
CC_SAFE_RETAIN(texture);
|
||||
_value.tex.texture = texture;
|
||||
|
||||
_value.tex.textureId = texture->getName();
|
||||
_value.tex.textureUnit = textureUnit;
|
||||
_type = Type::VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
void UniformValue::setInt(int value)
|
||||
{
|
||||
CCASSERT(_uniform->type == GL_INT, "Wrong type: expecting GL_INT");
|
||||
|
@ -218,7 +246,6 @@ void UniformValue::setVec3v(ssize_t size, const Vec3* pointer)
|
|||
_value.v3f.pointer = (const float*)pointer;
|
||||
_value.v3f.size = (GLsizei)size;
|
||||
_type = Type::POINTER;
|
||||
|
||||
}
|
||||
|
||||
void UniformValue::setVec4(const Vec4& value)
|
||||
|
@ -243,6 +270,20 @@ void UniformValue::setMat4(const Mat4& value)
|
|||
_type = Type::VALUE;
|
||||
}
|
||||
|
||||
UniformValue& UniformValue::operator=(const UniformValue& o)
|
||||
{
|
||||
_uniform = o._uniform;
|
||||
_glprogram = o._glprogram;
|
||||
_type = o._type;
|
||||
_value = o._value;
|
||||
|
||||
if (_uniform->type == GL_SAMPLER_2D)
|
||||
{
|
||||
CC_SAFE_RETAIN(_value.tex.texture);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// VertexAttribValue
|
||||
|
@ -396,7 +437,13 @@ GLProgramState::~GLProgramState()
|
|||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
Director::getInstance()->getEventDispatcher()->removeEventListener(_backToForegroundlistener);
|
||||
#endif
|
||||
|
||||
|
||||
// _uniforms must be cleared before releasing _glprogram since
|
||||
// the destructor of UniformValue will call a weak pointer
|
||||
// which points to the member variable in GLProgram.
|
||||
_uniforms.clear();
|
||||
_attributes.clear();
|
||||
|
||||
CC_SAFE_RELEASE(_glprogram);
|
||||
}
|
||||
|
||||
|
@ -446,7 +493,7 @@ bool GLProgramState::init(GLProgram* glprogram)
|
|||
|
||||
for(auto &uniform : _glprogram->_userUniforms) {
|
||||
UniformValue value(&uniform.second, _glprogram);
|
||||
_uniforms[uniform.second.location] = value;
|
||||
_uniforms[uniform.second.location] = std::move(value);
|
||||
_uniformsByName[uniform.first] = uniform.second.location;
|
||||
}
|
||||
|
||||
|
@ -455,10 +502,14 @@ bool GLProgramState::init(GLProgram* glprogram)
|
|||
|
||||
void GLProgramState::resetGLProgram()
|
||||
{
|
||||
CC_SAFE_RELEASE(_glprogram);
|
||||
_glprogram = nullptr;
|
||||
// _uniforms must be cleared before releasing _glprogram since
|
||||
// the destructor of UniformValue will call a weak pointer
|
||||
// which points to the member variable in GLProgram.
|
||||
_uniforms.clear();
|
||||
_attributes.clear();
|
||||
|
||||
CC_SAFE_RELEASE(_glprogram);
|
||||
_glprogram = nullptr;
|
||||
// first texture is GL_TEXTURE1
|
||||
_textureUnitIndex = 1;
|
||||
_nodeBinding = nullptr;
|
||||
|
@ -811,13 +862,45 @@ void GLProgramState::setUniformMat4(GLint uniformLocation, const Mat4& value)
|
|||
void GLProgramState::setUniformTexture(const std::string& uniformName, Texture2D *texture)
|
||||
{
|
||||
CCASSERT(texture, "Invalid texture");
|
||||
setUniformTexture(uniformName, texture->getName());
|
||||
auto v = getUniformValue(uniformName);
|
||||
if (v)
|
||||
{
|
||||
if (_boundTextureUnits.find(uniformName) != _boundTextureUnits.end())
|
||||
{
|
||||
v->setTexture(texture, _boundTextureUnits[uniformName]);
|
||||
}
|
||||
else
|
||||
{
|
||||
v->setTexture(texture, _textureUnitIndex);
|
||||
_boundTextureUnits[uniformName] = _textureUnitIndex++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CCLOG("cocos2d: warning: Uniform not found: %s", uniformName.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void GLProgramState::setUniformTexture(GLint uniformLocation, Texture2D *texture)
|
||||
{
|
||||
CCASSERT(texture, "Invalid texture");
|
||||
setUniformTexture(uniformLocation, texture->getName());
|
||||
auto v = getUniformValue(uniformLocation);
|
||||
if (v)
|
||||
{
|
||||
if (_boundTextureUnits.find(v->_uniform->name) != _boundTextureUnits.end())
|
||||
{
|
||||
v->setTexture(texture, _boundTextureUnits[v->_uniform->name]);
|
||||
}
|
||||
else
|
||||
{
|
||||
v->setTexture(texture, _textureUnitIndex);
|
||||
_boundTextureUnits[v->_uniform->name] = _textureUnitIndex++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CCLOG("cocos2d: warning: Uniform at location not found: %i", uniformLocation);
|
||||
}
|
||||
}
|
||||
|
||||
void GLProgramState::setUniformTexture(const std::string& uniformName, GLuint textureId)
|
||||
|
|
|
@ -71,6 +71,8 @@ public:
|
|||
*/
|
||||
UniformValue(Uniform *uniform, GLProgram* glprogram);
|
||||
|
||||
UniformValue(const UniformValue& o);
|
||||
|
||||
/**Destructor.*/
|
||||
~UniformValue();
|
||||
/**@{
|
||||
|
@ -101,12 +103,23 @@ public:
|
|||
Set texture to uniform value.
|
||||
@param textureId The texture handle.
|
||||
@param textureUnit The binding texture unit to be used in shader.
|
||||
@deprecated please use setTexture(Texture2D* texture, GLuint textureUnit) instead,
|
||||
Passing a `textureId` may trigger texture lost issue (https://github.com/cocos2d/cocos2d-x/issues/16871).
|
||||
*/
|
||||
void setTexture(GLuint textureId, GLuint textureUnit);
|
||||
CC_DEPRECATED_ATTRIBUTE void setTexture(GLuint textureId, GLuint textureUnit);
|
||||
|
||||
/**
|
||||
Set texture to uniform value.
|
||||
@param texture The texture.
|
||||
@param textureUnit The binding texture unit to be used in shader.
|
||||
*/
|
||||
void setTexture(Texture2D* texture, GLuint textureUnit);
|
||||
|
||||
/**Apply the uniform value to openGL pipeline.*/
|
||||
void apply();
|
||||
|
||||
UniformValue& operator=(const UniformValue& o);
|
||||
|
||||
protected:
|
||||
|
||||
enum class Type {
|
||||
|
@ -134,8 +147,9 @@ protected:
|
|||
float v4Value[4];
|
||||
float matrixValue[16];
|
||||
struct {
|
||||
GLuint textureId;
|
||||
GLuint textureId; // textureId will be deprecated since we use 'texture->getName()' to get textureId.
|
||||
GLuint textureUnit;
|
||||
Texture2D* texture;
|
||||
} tex;
|
||||
struct {
|
||||
const float* pointer;
|
||||
|
@ -317,7 +331,11 @@ public:
|
|||
void setUniformMat4(const std::string& uniformName, const Mat4& value);
|
||||
void setUniformCallback(const std::string& uniformName, const std::function<void(GLProgram*, Uniform*)> &callback);
|
||||
void setUniformTexture(const std::string& uniformName, Texture2D *texture);
|
||||
void setUniformTexture(const std::string& uniformName, GLuint textureId);
|
||||
/**
|
||||
* @deprecated, please use setUniformTexture(const std::string& uniformName, Texture2D *texture) instead,
|
||||
* Passing a `textureId` may trigger texture lost issue (https://github.com/cocos2d/cocos2d-x/issues/16871).
|
||||
*/
|
||||
CC_DEPRECATED_ATTRIBUTE void setUniformTexture(const std::string& uniformName, GLuint textureId);
|
||||
/**@}*/
|
||||
|
||||
/** @{
|
||||
|
@ -335,7 +353,11 @@ public:
|
|||
void setUniformMat4(GLint uniformLocation, const Mat4& value);
|
||||
void setUniformCallback(GLint uniformLocation, const std::function<void(GLProgram*, Uniform*)> &callback);
|
||||
void setUniformTexture(GLint uniformLocation, Texture2D *texture);
|
||||
void setUniformTexture(GLint uniformLocation, GLuint textureId);
|
||||
/**
|
||||
* @deprecated, please use setUniformTexture(GLint uniformLocation, Texture2D *texture) instead,
|
||||
* Passing a `textureId` may trigger texture lost issue (https://github.com/cocos2d/cocos2d-x/issues/16871).
|
||||
*/
|
||||
CC_DEPRECATED_ATTRIBUTE void setUniformTexture(GLint uniformLocation, GLuint textureId);
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -132,8 +132,8 @@ void VRGenericRenderer::render(Scene* scene, Renderer* renderer)
|
|||
glGetIntegerv(GL_VIEWPORT, origViewport);
|
||||
glViewport(0, 0, _texSize.width, _texSize.height);
|
||||
|
||||
renderDistortionMesh(_leftDistortionMesh, texture->getName());
|
||||
renderDistortionMesh(_rightDistortionMesh, texture->getName());
|
||||
renderDistortionMesh(_leftDistortionMesh, texture);
|
||||
renderDistortionMesh(_rightDistortionMesh, texture);
|
||||
|
||||
|
||||
glViewport(origViewport[0], origViewport[1], origViewport[2], origViewport[3]);
|
||||
|
@ -144,14 +144,14 @@ void VRGenericRenderer::render(Scene* scene, Renderer* renderer)
|
|||
CHECK_GL_ERROR_DEBUG();
|
||||
}
|
||||
|
||||
void VRGenericRenderer::renderDistortionMesh(DistortionMesh *mesh, GLint textureID)
|
||||
void VRGenericRenderer::renderDistortionMesh(DistortionMesh *mesh, Texture2D* texture)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mesh->_arrayBufferID);
|
||||
|
||||
_glProgramState->setVertexAttribPointer("a_position", 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)(0 * sizeof(float)));
|
||||
_glProgramState->setVertexAttribPointer("a_textureCoord", 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)(2 * sizeof(float)));
|
||||
_glProgramState->setVertexAttribPointer("a_vignette", 1, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)(4 * sizeof(float)));
|
||||
_glProgramState->setUniformTexture("u_textureSampler", textureID);
|
||||
_glProgramState->setUniformTexture("u_textureSampler", texture);
|
||||
|
||||
_glProgramState->apply(Mat4::IDENTITY);
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ public:
|
|||
|
||||
protected:
|
||||
void setupGLProgram();
|
||||
void renderDistortionMesh(DistortionMesh *mesh, GLint textureID);
|
||||
void renderDistortionMesh(DistortionMesh *mesh, Texture2D* texture);
|
||||
DistortionMesh* createDistortionMesh(VREye::EyeType eyeType);
|
||||
|
||||
experimental::FrameBuffer* _fb;
|
||||
|
|
|
@ -786,6 +786,7 @@ void Sprite3DEffectTest::addNewSpriteWithCoords(Vec2 p)
|
|||
material->setTechnique("outline_noneskinned");
|
||||
sprite->setMaterial(material);
|
||||
sprite->setScale(6.f);
|
||||
Director::getInstance()->getTextureCache()->removeUnusedTextures();
|
||||
|
||||
//add to scene
|
||||
addChild( sprite );
|
||||
|
|
Loading…
Reference in New Issue