Search code examples
cocos2d-xcocos2d-x-3.0

Update color data dynamically in cocos2d-x


I want to create some effects in cocos2d-x by updating raw color data of sprite, does cocos2d-x supply any ways to do that?

Update: My buffer is 4-bytes (A-R-G-B) for each pixels, viewport dimensions are 640x480. So, the buffer has 640 * 480 * 4 = 1228800 bytes in length and I update its content frequently.


Solution

  • This solution regenerates the texture each time it is changed. Note: the texture in this code uses the format RGBA - not ARGB.

    The data(/texel) array m_TextureData and the sprite are allocated only once but the Texture2D object has to be released and recreated every time which might be a performance issue.

    Note: the class names are the new ones from Cocos2d-x 3.1.x. In the main loop there's an alternative part for 2.2.x users. To use that one you have to use also the old class names (like ccColor4B, CCTexture2D, CCSprite).

    in header:

    Color4B    *m_TextureData;
    Texture2D    *m_Texture;
    Sprite       *m_Sprite;
    

    in implementation:

    int w = 640; // width  of texture
    int h = 480; // height of texture
    
    m_TextureData = new Color4B[w * h];
    

    set colors directly - e.g.:

    Color4B white;
    white.r = 255;
    white.g = 255;
    white.b = 255;
    white.a = 255;
    m_TextureData[i] = white; // i is an index running from 0 to w*h-1
    

    use data to initialize texture:

    CCSize contentSize;
    contentSize.width  = w;
    contentSize.height = h;
    
    m_Texture = new Texture2D;
    m_Texture->initWithData(m_TextureData, kCCTexture2DPixelFormat_RGBA8888, w, h, contentSize);
    

    create a Sprite with this texture:

    m_Sprite = Sprite::createWithTexture(m_Texture);
    m_Sprite->retain();
    

    add m_Sprite to your scene

    in main loop:
    to change color/texels of texture dynamically modify m_TextureData:

    m_TextureData[i] = ...;
    

    in Cocos2d-x 2.x:
    In 2.2.x you actually have to release the old texture and create a new one:

    m_Texture->release(); // make sure that ccGLDeleteTexture() is called internally to prevent memory leakage
    
    m_Texture = new Texture2D;
    m_Texture->initWithData(m_TextureData, kCCTexture2DPixelFormat_RGBA8888, w, h, contentSize);
    
    m_Sprite->setTexture(m_Texture); // update sprite with new texture
    

    in Cocos2d-x 3.1.x

    m_Texture->updateWithData(m_TextureData, 0, 0, w, h);
    

    Later, don't forget to clean up.
    in destructor:

    m_Sprite->release();
    m_Texture->release();
    delete [] m_TextureData;