所以,我试图找到屏幕上任何特定颜色像素的位置。
以下代码有效,但非常慢,因为我必须迭代每个像素坐标,并且有很多。
有没有办法改进以下代码以提高效率?
// 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];
答案 0 :(得分:1)
您可以(并且应该)一次只读取一个像素。使OpenGL快速化的方法是将所有内容打包到尽可能少的操作中。这有两种方式(读取和写入GPU)。
尝试在一次调用中读取整个纹理,并从结果数组中找到红色像素。如下所示。
另请注意,一般来说,逐行遍历位图是个好主意,这意味着要反转for -loops的顺序(外部为y [rows],内部为x)
// 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;
答案 1 :(得分:0)
每次都不要对你的缓冲区进行malloc,只需重用相同的缓冲区; malloc很慢!请看看Apple的Memory Usage Documentation。
我不知道任何可以更快地执行此操作的算法,但这可能会有所帮助。