智慧 + 毅力 = 无所不能

正确性、健壮性、可靠性、效率、易用性、可读性、可复用性、兼容性、可移植性...

导航

cocos2dx 获取精灵的高亮效果

Posted on 2014-12-05 14:03  Bill Yuan  阅读(3953)  评论(0编辑  收藏  举报

转自:http://blog.csdn.net/tyxkzzf/article/details/38703883

CCSprite* getHighlightSprite(CCSprite* normalsprite) {
    if ( !normalsprite) {
        return CreateDefaultSprite();
    }
    //CCSprite转成CCimage
    CCPoint p = normalsprite->getAnchorPoint();
    normalsprite->setAnchorPoint(ccp(0, 0));
    CCRenderTexture *outTexture = CCRenderTexture::create((int)normalsprite->getContentSize().width, (int)normalsprite->getContentSize().height);
    outTexture->begin();
    normalsprite->visit();
    outTexture->end();
    normalsprite->setAnchorPoint(p);
    
    CCImage* finalImage = outTexture->newCCImage();
    unsigned char *pData = finalImage->getData();
    int iIndex = 0;
    
    for (int i = 0; i < finalImage->getHeight(); i ++) {
        for (int j = 0; j < finalImage->getWidth(); j ++) {
            // highlight
            int iHightlightPlus = 50;
            int iBPos = iIndex;
            unsigned int iB = pData[iIndex];
            iIndex ++;
            unsigned int iG = pData[iIndex];
            iIndex ++;
            unsigned int iR = pData[iIndex];
            iIndex ++;
            //unsigned int o = pData[iIndex];
            iIndex ++;  //原来的示例缺少
            iB = (iB + iHightlightPlus > 255 ? 255 : iB + iHightlightPlus);
            iG = (iG + iHightlightPlus > 255 ? 255 : iG + iHightlightPlus);
            iR = (iR + iHightlightPlus > 255 ? 255 : iR + iHightlightPlus);
            //            iR = (iR < 0 ? 0 : iR);
            //            iG = (iG < 0 ? 0 : iG);
            //            iB = (iB < 0 ? 0 : iB);
            pData[iBPos] = (unsigned char)iB;
            pData[iBPos + 1] = (unsigned char)iG;
            pData[iBPos + 2] = (unsigned char)iR;
        }
    }
    
    CCTexture2D *texture = new CCTexture2D;
    texture->initWithImage(finalImage);
    CCSprite* newSprite = CCSprite::createWithTexture(texture);
    delete finalImage;
    texture->release();
    
    return newSprite;
}

这里有更详细的一片介绍文章《Cocos2dx如何反白高亮CCSprite》点击打开链接

在做游戏时遇到需要使用纯白色高亮精灵的场合,尝试了很多办法没有解决问题,目前有以下几种解法:  最简单当然是切换成和精灵图片一样的另一张纯白图片。 另外就是使用glTexEnvi,具体如下:

重写一个类继承CCSprite, 改写draw 函数,如下代码:

void YourSprite::setHightlight(bool hightlight)
{
    if (m_hightlight != hightlight)
    {
        m_hightlight = hightlight;
        if (m_hightlight)
        {
            ccBlendFunc blendFunc = {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA};
            setBlendFunc(blendFunc);
        }
        else
        {
            ccBlendFunc blendFunc = {CC_BLEND_SRC, CC_BLEND_DST};
            setBlendFunc(blendFunc);
        }
    }
}
    void     YourSprite::draw()

{

     CCNode::draw();


    CCAssert(! m_bUsesBatchNode, "");


    // Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
    // Needed states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
    // Unneeded states: -
    bool newBlend = m_sBlendFunc.src != CC_BLEND_SRC || m_sBlendFunc.dst != CC_BLEND_DST;
    if (newBlend)
    {
        glBlendFunc(m_sBlendFunc.src, m_sBlendFunc.dst);
    }


#define kQuadSize sizeof(m_sQuad.bl)
    if (m_pobTexture)
    {
        glBindTexture(GL_TEXTURE_2D, m_pobTexture->getName());
    }
    else
    {
        glBindTexture(GL_TEXTURE_2D, 0);
    }


    if (m_hightlight)
    {
        glActiveTexture( GL_TEXTURE0 );


        //the magic
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
        glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD); //you can change me... GL_REPLACE, GL_SUBSTRACT produce nice effects
        glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS); //setColor
        glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE); //your texture
    }
    long offset = (long)&m_sQuad;


    // vertex
    int diff = offsetof(ccV3F_C4B_T2F, vertices);
    glVertexPointer(3, GL_FLOAT, kQuadSize, (void*)(offset + diff));


    // color
    diff = offsetof( ccV3F_C4B_T2F, colors);
    glColorPointer(4, GL_UNSIGNED_BYTE, kQuadSize, (void*)(offset + diff));


    // tex coords
    diff = offsetof( ccV3F_C4B_T2F, texCoords);
    glTexCoordPointer(2, GL_FLOAT, kQuadSize, (void*)(offset + diff));


    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);


    if( newBlend )
    {
        glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST);
    }


#if CC_SPRITE_DEBUG_DRAW == 1
    // draw bounding box
    CCSize s = m_tContentSize;
    CCPoint vertices[4] = {
        ccp(0,0), ccp(s.width,0),
        ccp(s.width,s.height), ccp(0,s.height)
    };
    ccDrawPoly(vertices, 4, true);
#elif CC_SPRITE_DEBUG_DRAW == 2
    // draw texture box
    const CCSize& s = m_obRect.size;
    const CCPoint& offsetPix = getOffsetPositionInPixels();
    CCPoint vertices[4] = {
        ccp(offsetPix.x,offsetPix.y), ccp(offsetPix.x+s.width,offsetPix.y),
        ccp(offsetPix.x+s.width,offsetPix.y+s.height), ccp(offsetPix.x,offsetPix.y+s.height)
    };
    ccDrawPoly(vertices, 4, true);
#endif // CC_SPRITE_DEBUG_DRAW


    if (m_hightlight)
    {
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    }

}