2013-07-25 122 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;