In CCParticleBatchNode.cpp, there is one function call which I can’t understand:
`void CCParticleBatchNode::removeChild(CCNode* child, bool cleanup)
{
…
// particle could be reused for self rendering
*pChild->setBatchNode(NULL);*
...
}`
pChild~~>setBatchNode. What is this line used for? And what does self rendering mean?
The reason I concern it is because I got one bug recently. It crashes when calling glDrawElement when rendering labels and particle batch nodes simultaneously. I worked on it for a long time and am 99% sure that the bug hides inside the engine. After I comment this sentence Child~~>setBatchNode(NULL); everything goes well and no crash any more. I can see a lot of memory operations inside the function and are very suspicious if there are any potential bug or loophole in it.
Could any one answer my question please?
1 What is this function setBatchNode() used for? What does self rendering mean?
2 Could any engine developer check if all memory operations inside setBatchNode() is completely correct? I’m very doubt about that.
Thanks in advance.
I confirm this issue.
Cocos2dx crashes trying to render CCLabelBMFont if CCParticleSystemQuad was previously removed from CCParticleBatchNode.
And yes, commenting pChild->setBatchNode(NULL); in CCParticleBatchNode::removeChild prevents the crash.
@Nichos Liu
I guess ‘self rendering’ means that you are able to continue rendering of the particle system as a standalone group of triangles after you detach it from CCParticleBatchNode. If batch node is not set to NULL, particle system still thinks that it has a batch parent and behaves improperly. However I can’t imagine a use case for such feature. Usually particle system is detached from its parent batch when it’s being removed from the scene.
Ok, it seems I’ve found a solution.
In CCParticleSystemQuad::setBatchNode after
glDeleteBuffers(2, &m_pBuffersVBO[0]);
there is should be
memset(m_pBuffersVBO, 0, sizeof(m_pBuffersVBO));
VBO names (m_pBuffersVBO) should be zeroed because, they will be deleted again in CCParticleSystemQuad::setupVBO() when the particle system is detached from the batch. The fact is that at that time those VBOs belong to another node (in our case that is CCLabelBMFont).
You are welcome
I sent a pull request to https://github.com/cocos2d/cocos2d-x/ and waiting for review. I hope the next release version won’t suffer from this bug.
Also I’ve noticed that removing the particle system which is attached to the batch is somewhat ineffective since it recreates VBOs (the vertex and index buffers stored in GPU mem) and then deletes them anyway. This was done to allow the particles detached from the batch to be reused for self rendering, but I believe that this use case is more rare than detaching and total remove.
Yes, I thought that VAOs could be deleted improperly too, since I found this bug in 2.1.4, which I currently use.
But then I discovered that in ‘develop’ branch the deletion of VAOs is fixed, but the deletion of VBOs is still faulty, so I made a pull request which fixes this issue. https://github.com/cocos2d/cocos2d-x/pull/3359
You may try the test project I mentioned in the comments to the pull request.
Yes, I thought that VAOs could be deleted improperly too, since I found this bug in 2.1.4, which I currently use.
But then I discovered that in ‘develop’ branch the deletion of VAOs is fixed, but the deletion of VBOs is still faulty, so I made a pull request which fixes this issue. https://github.com/cocos2d/cocos2d-x/pull/3359
You may try the test project I mentioned in the comments to the pull request.