2013-07-25 126 views
0

所以,我试图找到屏幕上任何像素的位置,这是特定的颜色。从CCRenderTexture获取像素的颜色

下面的代码有效,但速度非常慢,因为我必须迭代每个像素坐标,并且有很多。

有没有什么办法可以改善下面的代码以提高效率?

// 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

从帧缓冲区读取像素很慢,特别是如果你逐像素地进行读取。取得渲染纹理的纹理内存,并在没有glReadPixel的情况下进行迭代,应该快得多! – LearnCocos2D

+0

@ LearnCocos2D嘿,伙计!我会怎么做呢?你有没有可以分享的例子?然后我可以将你的回答标记为正确:) – Sneaksta

+0

我的错误是,CCTexture2D不保留内存缓冲区,无论如何它都在GL内存中。 – LearnCocos2D

回答

0

每次不要malloc你的缓冲区,只是重用相同的缓冲区; malloc很慢!请看看苹果的Memory Usage Documentation

我不知道任何算法可以做得更快,但这可能会有所帮助。

+0

好的,这是一个很好的观点。我将如何去实现重复使用相同的缓冲区? – Sneaksta

+0

只需在开始迭代之前执行malloc一次。 – Wilson

+1

我刚刚尝试过,但似乎没有让迭代更快。 :( – Sneaksta

1

您可以(也应该)一次读取多于一个像素。使OpenGL更快的方法是将所有东西打包成尽可能少的操作。这两种方式都有效(读取和写入GPU)。

尝试在一次调用中读取整个纹理,然后从结果数组中查找红色像素。如下。

还要注意,一般来说它是遍历由行位图的行,这意味着反向的用于-loops的顺序是一个好主意(在外侧y [行],其中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;