Render Texture Get Percentage of Transparent

Hello all,

Am using cocos2d-JS 3.5
I need to calculate transparent percentage of render texture.

Render texture created by,

var canvas = new cc.RenderTexture(1024,768, 2);
        canvas.x = 512;
        canvas.y = 384;
        this.addChild(canvas,1);

Am using glreadpixel method to calculate transparency. Here is My Code.

getPercentageTransparent:function()
    {
        //
        var s=this.getSprite().getContentSize();
        var tx = s.width;
        var ty = s.height;

        var bitsPerPixel                = 4 * 8;
        var bytesPerPixel               = bitsPerPixel / 8;
        var bytesPerRow					= bytesPerPixel * tx;
        var myDataLength			= bytesPerRow * ty;

        var numberOfPixels              = tx * ty;
        var numberOfTransparent       = 0;

        var rawImagePixels = new Uint8Array(myDataLength);
        this.begin();
        gl.readPixels(0,0,tx,ty, gl.RGBA,gl.UNSIGNED_BYTE, rawImagePixels);
        this.end();

        var x,y;

        for(y = 0; y < ty; y++) {
            // just want the last byte (alpha) for each pixel
            for(x = 0; x < tx; x++) {
                var alpha = rawImagePixels[(y * 4 * tx + ((x * 4)+3))];

                if(alpha < 1)
                {
                    numberOfTransparent++;
                }
            }
        }
        cc.log("Number of pixels"+numberOfPixels);
        cc.log("Number of Trasparent"+numberOfTransparent);
        return (numberOfTransparent/numberOfPixels)*100;
    }, 

This works fine in Web.

Same thing i have done for JS Binding. I have added method in Rendertexture.cpp class. Here is Code

float RenderTexture::getPercentageTransparent()
{
    
    //this->clear(0.0, 0.0, 0.0, 0.0);
    
    Size s=this->_texture->getContentSize();
    int tx = s.width;
    int ty = s.height;
    
    int bitsPerPixel                = 4 * 8;
    int bytesPerPixel               = bitsPerPixel / 8;
    int bytesPerRow					= bytesPerPixel * tx;
    int myDataLength			= bytesPerRow * ty;
    
    int numberOfPixels              = tx * ty;
    float numberOfTransparent       = 0;
    
    //GLubyte *buffer	= malloc(sizeof(GLubyte)*myDataLength);
    
    // GLubyte *buffer	= malloc(sizeof(GLubyte)*myDataLength);
    
    GLubyte *rawImagePixels = (GLubyte *)malloc(myDataLength);
    
    CCLOG("RGB value %hhu,%hhu and %hhu  %hhu",rawImagePixels[0],rawImagePixels[1],rawImagePixels[2],rawImagePixels[3]);
    
    this->begin();
    glReadPixels(0,0,tx,ty,GL_RGBA,GL_UNSIGNED_BYTE, rawImagePixels);
    this->end();
    
    CCLOG("RGB value %hhu,%hhu and %hhu  %hhu",rawImagePixels[0],rawImagePixels[1],rawImagePixels[2],rawImagePixels[3]);
    int x,y;
    for(y = 0; y < ty; y++) {
        // just want the last byte (alpha) for each pixel
        for(x = 0; x < tx; x++) {
            GLubyte alpha = rawImagePixels[(y * 4 * tx + ((x * 4)+3))];
            if(alpha == 0) {
                numberOfTransparent++;
            }
        }
    }
    
    free(rawImagePixels);
    CCLOG("Transparent count %f",numberOfTransparent);
    CCLOG("number of pixel %d",numberOfPixels
    return (numberOfTransparent/numberOfPixels)*100;   
}

But always am getting transparent value as ZERO. I have wasted nearly 1 day.
Where am doing wrong? Can anyone please help me out.

Regards
Gurudath

Hi Gurudath,
Your above solution works fine for above only if we set “rendreMode” is set to “2” (Webgl).
I want to know something which works for Canvas mode

I know this has a lot of time, but I came across it and I decided to help, it works well with version 3.17

float Diversos::PegaPorcentagemTransparente(RenderTexture * rendertexture)
{
    //rendertexture->clear(0.0, 0.0, 0.0, 0.0);
    Director::getInstance()->getRenderer()->render(); // Precisa renderizar para pegar uma informação válida.
    auto img  = rendertexture->newImage();
    
    int w           = img->getWidth();
    int h           = img->getHeight();
    auto data       = img->getData();
    float p_total   = w * h;
    float p_alpha   = 0;
    
    auto rgbProfile = 3;
    if(img->hasAlpha())
        rgbProfile = 4;
    
    // iterate over each pixel in the image and set its value to green just for testing
    for (int y = 0; y < h; y++)
    {
        for (int x = 0; x < w; x++)
        {
            unsigned char * pixel = data + (x + y * img->getWidth()) * rgbProfile;
            //CCLOG("Pixel: %d, %d, %d, %d", * pixel, *(pixel + 1), *(pixel + 2), *(pixel + 3));
            
            //Color4B tempValues; //  pixel value at this position
            //tempValues.r = * pixel;
            //tempValues.g = *(pixel + 1);
            //tempValues.b = *(pixel + 2);
            //tempValues.a = *(pixel + 3);
            
            if( *(pixel + 3) == 0 )
                p_alpha++;
        }
    }
    return (p_alpha / p_total) * 100;
}