我昨晚上进行了移植,现在把代码贴上来,并没有实现效果,我得调试一下,有很奇怪的bug,坐标会偏移,不过3.2版本代码大概就是我这样了,我再核对一下,希望能成功
PS:我根据自己的习惯改了一些命名和编程风格,但是没有改变算法本身,因为我也希望我能用上,至于vsh和fsh两个文件,还请自行拷贝然后放到Resource下面,使用方法按照那个博客上的就行了,如果我试成功了,我会再回复这个帖子的
#ifndef PIXEL_COLLISION_DETECTION_H_
#define PIXEL_COLLISION_DETECTION_H_
#include "cocos2d.h"
USING_NS_CC;
class PixelCollisionDetection {
public:
PixelCollisionDetection();
~PixelCollisionDetection();
static PixelCollisionDetection* getInstance();
bool isCollided(Sprite *pObjA, Sprite *pObjB, RenderTexture *pRenderTex);
private:
DISALLOW_COPY_AND_ASSIGN(PixelCollisionDetection);
bool init();
GLProgram *pGLProgram_;;
Color4B *pPixelBuffer_;
int uniformColorRed_;
int uniformColorBlue_;
};
#endif
```
#include "pixel_collision_detection.h"
static PixelCollisionDetection *pInstance = nullptr;
PixelCollisionDetection::PixelCollisionDetection()
: pGLProgram_(nullptr),
pPixelBuffer_(nullptr),
uniformColorRed_(255),
uniformColorBlue_(255)
{
}
PixelCollisionDetection::~PixelCollisionDetection()
{
CC_SAFE_DELETE(pInstance);
CC_SAFE_RELEASE(pGLProgram_);
CC_SAFE_DELETE_ARRAY(pPixelBuffer_);
}
PixelCollisionDetection* PixelCollisionDetection::getInstance()
{
if(!pInstance) {
pInstance = new PixelCollisionDetection;
if(!pInstance || !pInstance->init())
{
delete pInstance;
pInstance = nullptr;
}
}
return pInstance;
}
bool PixelCollisionDetection::isCollided(Sprite *pObjA, Sprite *pObjB, RenderTexture *pRenderTex)
{
bool bRet = false;
Rect rectA = pObjA->getBoundingBox();
Rect rectB = pObjB->getBoundingBox();
if(rectA.intersectsRect(rectB))
{
float tempX = 0.0f;
float tempY = 0.0f;
float tempWid = 0.0f;
float tempHgt = 0.0f;
//more optimization,one rect is completely inside another
if(rectA.getMaxX() > rectB.getMinX()) {
tempX = rectB.getMinX();
tempWid = rectA.getMaxX() - rectB.getMinX();
}
else {
tempX = rectA.getMinX();
tempWid = rectB.getMaxX() - rectA.getMinX();
}
if (rectB.getMaxY() < rectA.getMaxY()) {
tempY = rectA.getMinY();
tempHgt = rectB.getMaxY() - rectA.getMinY();
}
else {
tempY = rectB.getMinY();
tempHgt = rectA.getMaxY() - rectB.getMinY();
}
Rect intersectionRect(tempX * CC_CONTENT_SCALE_FACTOR(), tempY * CC_CONTENT_SCALE_FACTOR(),
tempWid * CC_CONTENT_SCALE_FACTOR(), tempHgt * CC_CONTENT_SCALE_FACTOR());
unsigned x = intersectionRect.origin.x;
unsigned y = intersectionRect.origin.y;
unsigned w = intersectionRect.size.width;
unsigned h = intersectionRect.size.height;
//total pixels
unsigned pixelsNum = w * h;
pObjA->setGLProgram(pGLProgram_);
pObjB->setGLProgram(pGLProgram_);
pGLProgram_->use();
pRenderTex->beginWithClear(0.0f, 0.0f, 0.0f, 0.0f);
glUniform1i(uniformColorRed_, 255);
glUniform1i(uniformColorBlue_, 0);
//set an appropriate blend mode so that we can get a new color by two color blending
pObjA->setBlendFunc(BlendFunc::ADDITIVE);
pObjA->visit();
pObjA->setGLProgram(ShaderCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR));
pObjA->setBlendFunc(BlendFunc::ALPHA_PREMULTIPLIED);
glUniform1i(uniformColorRed_, 0);
glUniform1i(uniformColorBlue_, 255);
pObjB->setBlendFunc(BlendFunc::ADDITIVE);
pObjB->visit();
pObjB->setGLProgram(ShaderCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR));
pObjB->setBlendFunc(BlendFunc::ALPHA_PREMULTIPLIED);
glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pPixelBuffer_);
pRenderTex->end();
unsigned step = 1;
for(int i = 0; i < pixelsNum; i += step)
{
Color4B pxl = pPixelBuffer_*;
//both have two color,it must be the collision area
if(pxl.r > 0 && pxl.b > 0)
{
bRet = true;
break;
}
}
}
return bRet;
}
//-------------------private----------------------
bool PixelCollisionDetection::init()
{
bool bRet = false;
do
{
pGLProgram_ = GLProgram::createWithFilenames("solid_vs.vsh", "solid_fs.fsh");
pGLProgram_->retain();
pGLProgram_->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
pGLProgram_->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORD);
pGLProgram_->link();
pGLProgram_->updateUniforms();
pGLProgram_->use();
uniformColorRed_ = glGetUniformLocation(pGLProgram_->getProgram(), "u_color_red");
uniformColorBlue_ = glGetUniformLocation(pGLProgram_->getProgram(), "u_color_blue");
pPixelBuffer_ = new Color4B;
bRet = true;
} while(0);
return bRet;
}
```
*