Armature设置shader,使用“遍历BoneDic”设置“bone->getDisplayRenderNode();”的方式,只能设置当前用到的骨骼的精灵。由于Armature不止有骨骼动画,还夹杂着帧动画,之后出现的精灵没有被设置shader,这个要怎么解决??
您好。请问这个问题您解决了吗?我尝试了将draw()重写,然后在里面执行你提到的遍历bone设置shader。但是效率很低。应该会有更优化的方法。不知道您是否实现了?!
通过在网上的查找,这里提供了一个可用的解决方案。
这一个函数,对每一个bone的每一个child设置shader。
void ShaderArmature::initShader(bool shaderState){
//Traverse every bone to set shader
for (auto& object : _boneDic)
{
if (Bone *bone = dynamic_cast<Bone *>(object.second))
{
if (bone == nullptr)
continue;
//-----------------!! IMPORTANT !!-----------------
//Each bone may have more than one child, like several frames, also need to assign shader to them
//Without this step, only the first frame will have the shader effect.
const Vector<DecorativeDisplay*> list = bone->getDisplayManager()->getDecorativeDisplayList();
for (auto& display : list)
{
Node* node = display->getDisplay();
if (node == nullptr)
continue;
if (shaderState){
auto program = new GLProgram();
program->initWithByteArrays(vertSource, fragSource);
node->setGLProgram(program);
program->autorelease();
CHECK_GL_ERROR_DEBUG();
program->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
program->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
program->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
CHECK_GL_ERROR_DEBUG();
program->link();
CHECK_GL_ERROR_DEBUG();
program->updateUniforms();
CHECK_GL_ERROR_DEBUG();
}
else{//addNormal shader
node->setGLProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP));
}
}
}
}
}
在机器上实测可用。