I am trying to port the pixel perfect collision detection in Cocos2d-x the original version was made for Cocos2D and can be found here: http://www.cocos2d-iphone.org/forums/topic/pixel-perfect-collision-detection-using-color-blending/
Here is my code for the Cocos2d-x version
bool CollisionDetection::areTheSpritesColliding(cocos2d::CCSprite *spr1, cocos2d::CCSprite *spr2, bool pp, CCRenderTexture* _rt) { bool isColliding = false; CCRect intersection; CCRect r1 = spr1->boundingBox(); CCRect r2 = spr2->boundingBox(); intersection = CCRectMake(fmax(r1.getMinX(),r2.getMinX()), fmax( r1.getMinY(), r2.getMinY()) ,0,0); intersection.size.width = fmin(r1.getMaxX(), r2.getMaxX() - intersection.getMinX()); intersection.size.height = fmin(r1.getMaxY(), r2.getMaxY() - intersection.getMinY()); // Look for simple bounding box collision if ( (intersection.size.width>0) && (intersection.size.height>0) ) { // If we're not checking for pixel perfect collisions, return true if (!pp) { return true; } unsigned int x = intersection.origin.x; unsigned int y = intersection.origin.y; unsigned int w = intersection.size.width; unsigned int h = intersection.size.height; unsigned int numPixels = w * h; //CCLog("Intersection X and Y %d, %d", x, y); //CCLog("Number of pixels %d", numPixels); // Draw into the RenderTexture _rt->beginWithClear( 0, 0, 0, 0); // Render both sprites: first one in RED and second one in GREEN glColorMask(1, 0, 0, 1); spr1->visit(); glColorMask(0, 1, 0, 1); spr2->visit(); glColorMask(1, 1, 1, 1); // Get color values of intersection area ccColor4B *buffer = (ccColor4B *)malloc( sizeof(ccColor4B) * numPixels ); glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, buffer); _rt->end(); // Read buffer unsigned int step = 1; for(unsigned int i=0; i 0 && color.g > 0) { isColliding = true; break; } } // Free buffer memory free(buffer); } return isColliding; }
My code is working perfectly if I send the "pp" parameter as false. That is if I do only a bounding box collision but I am not able to get it working correctly for the case when I need Pixel Perfect collision. I think the opengl masking code is not working as I intended.
Here is the code for "_rt"
_rt = CCRenderTexture::create(visibleSize.width, visibleSize.height); _rt->setPosition(ccp(origin.x + visibleSize.width * 0.5f, origin.y + visibleSize.height * 0.5f)); this->addChild(_rt, 1000000); _rt->setVisible(true); //For testing
I think I am making a mistake with the implementation of this CCRenderTexture
Can anyone guide me with what I am doing wrong ?
Thank you for your time :)
Finally solved the problem. Had to use custom opengl fragment shaders to shade one of the sprites completely RED and the other completely BLUE and then looping through glReadPixels values to find any pixel having both RED and BLUE pixels. (Blending has to be considered as well, we do not want to replace one pixel value by the other)
In-Depth information can be found on my blog post http://blog.muditjaju.infiniteeurekas.in/?p=1
You are not stepping through the buffer properly.
// Read buffer
unsigned int step = 1;
for(unsigned int i=0; i<numPixels; i+=step)
{
ccColor4B color = buffer;
if (color.r > 0 && color.g > 0)
{
isCollision = YES;
break;
}
}
source: http://www.cocos2d-iphone.org/forums/topic/pixel-perfect-collision-detection-using-color-blending/#post-337907
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With