简体   繁体   中英

Get colour of pixel from CCRenderTexture

So, I am trying to find the location of any pixels on the screen that are a specific colour.

The following code works, but is VERY slow, because I have to iterate over every single pixel co-ordinate, and there are a lot.

Is there any way to improve the following code to make it more efficient?

    // Detect the position of all red points in the sprite
    UInt8 data[4];

    CCRenderTexture* renderTexture = [[CCRenderTexture alloc] initWithWidth: mySprite.boundingBox.size.width * CC_CONTENT_SCALE_FACTOR()
                                                                     height: mySprite.boundingBox.size.height * CC_CONTENT_SCALE_FACTOR()
                                                                pixelFormat:kCCTexture2DPixelFormat_RGBA8888];
    [renderTexture begin];
    [mySprite draw];

    for (int x = 0; x < 960; x++)
    {
        for (int y = 0; y < 640; y++)
        {                
            ccColor4B *buffer = malloc(sizeof(ccColor4B));
            glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
            ccColor4B color = buffer[0];

            if (color.r == 133 && color.g == 215 && color.b == 44)
            {
                NSLog(@"Found the red point at x: %d y: %d", x, y);
            }
        }
    }

    [renderTexture end];
    [renderTexture release];

You can (and should) read more than just one pixel at a time. The way to make OpenGL fast, is to pack all your stuff into as few operations as possible. That works both ways (reading and writing to the GPU).

Try reading the whole texture in one call, and finding your red pixels from the resulting array. As below.

Also note, that generally speaking it is a good idea to traverse a bitmap row by row, which means reversing the order of for -loops (y [rows] on the outside, with x on the inside)

// Detect the position of all red points in the sprite
ccColor4B *buffer = new ccColor4B[ 960 * 640 ];

CCRenderTexture* renderTexture = [[CCRenderTexture alloc] initWithWidth: mySprite.boundingBox.size.width * CC_CONTENT_SCALE_FACTOR()
                                                                 height: mySprite.boundingBox.size.height * CC_CONTENT_SCALE_FACTOR()
                                                            pixelFormat:kCCTexture2DPixelFormat_RGBA8888];
[renderTexture begin];
[mySprite draw];

glReadPixels(0, 0, 940, 640, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

[renderTexture end];
[renderTexture release];

int i = 0;
for (int y = 0; y < 640; y++)
{
    for (int x = 0; x < 960; x++)
    {                            
        ccColor4B color = buffer[i];//the index is equal to y * 940 + x
        ++i;
        if (color.r == 133 && color.g == 215 && color.b == 44)
        {
            NSLog(@"Found the red point at x: %d y: %d", x, y);
        }
    }
}
delete[] buffer;

Don't malloc your buffer every time, just reuse the same buffer; malloc is slow! Please take a look at Apple's Memory Usage Documentation .

I don't know of any algorithms that can do this any faster, but this might help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM