Hi, While I have never needed to do perfect pixel collision I do need to do pixel perfect touch detection (i.e. ignore touch on pixels with alpha value = 0). That tutorial is correct for v2.x.
For version 3.x you need to force a render and you need to encapsulate glReadPixel inside a CustomCommand.
Here is my current getPixelColorAt method that I am currently using un cocos2d-x v3.x
unsigned long GlobalUtils::getPixelColorAt(Node* sprite, const Vec2& point)
{
float contentScale = CC_CONTENT_SCALE_FACTOR();
float width = sprite->getContentSize().width;
float height = sprite->getContentSize().height;
RenderTexture* pRenderer = RenderTexture::create(width, height);
Point pos = sprite->getPosition();
Point anchor = sprite->getAnchorPoint();
float rangle = sprite->getRotation();
float iScaleX = sprite->getScaleX();
float iScaleY = sprite->getScaleY();
Vec2 testPoint = Vec2((point.x + width/contentScale * anchor.x) * contentScale,
(point.y + height/contentScale * anchor.y) * contentScale);
KBRPixelReadNode* pixelReadNode = KBRPixelReadNode::create(testPoint);
pRenderer->begin();
sprite->setPosition(Vec2::ZERO);
sprite->setAnchorPoint(Vec2::ZERO);
sprite->setRotation(0.0f);
sprite->setScale(1.0f, 1.0f);
sprite->visit();
pixelReadNode->visit(); // IMPORTANT -> THIS WILL CALL KBRPixelReadNode::draw
pRenderer->end();
Director::getInstance()->getRenderer()->render(); //IMPORTANT -> THIS WILL ALLOW SYNCHRONOUS BEHAVIOR
if (pos.equals(Vec2::ZERO)) { //force dirty state, otherwise we would get weird draw behaviour because the model view transform would be wrong
sprite->setPosition(Vec2(-1, -1));
}
sprite->setRotation(rangle);
sprite->setPosition(pos);
sprite->setAnchorPoint(anchor);
sprite->setScale(iScaleX, iScaleY);
// IMPORTANT - AT THIS POINT KBRPixelReadNode::onDraw has already been executed and we can check the pixel color
return ((unsigned long) pixelReadNode->getPixelColor()[3]);
}
So basically there are two steps you need to go through to make sure that tutorial you have linked works on cocos2d-x v3.x.
1 - Don’t just use plain glReadPixels, create a custom command and add it to the renderer.
2 - Force a Renderer::render() to check pixel color synchronously
miguel12345, thanks! I tried something from above, but unfortunately i havn’t profound knowledges and enough experience with work of shaders and render textures.
happybirthday, it would be wonderful! Will be very grateful for you.