2010-03-10 72 views
0

我有一個簡單的iPhone應用程序,它使用OpenGL ES(v1)根據用戶的觸摸繪製一條線。在XCode模擬器中,代碼完美工作。但是,當我將應用程序安裝到iPod或iPhone上時,繪製線條時,OpenGL ES視圖會「閃爍」。如果我禁用線條繪製,則閃光燈消失。通過「閃光燈」,我的意思是背景圖像(這是一個OpenGL紋理)瞬間消失,然後再次出現。看起來好像整個場景被完全擦除和重繪。更新時出現iPod/iPhone OpenGL ES UIView閃爍

它處理線描的代碼如下:

renderLineFromPoint:(CGPoint)start toPoint:(CGPoint)end 
{ 
    static GLfloat*  vertexBuffer = NULL; 
    static NSUInteger vertexMax = 64; 
    NSUInteger   vertexCount = 0, 
    count, 
    i; 

    //Allocate vertex array buffer 
    if(vertexBuffer == NULL) 
     vertexBuffer = malloc(vertexMax * 2 * sizeof(GLfloat)); 

    //Add points to the buffer so there are drawing points every X pixels 
    count = MAX(ceilf(sqrtf((end.x - start.x) * (end.x - start.x) + (end.y - start.y) * (end.y - start.y))/kBrushPixelStep), 1); 
    for(i = 0; i < count; ++i) { 
     if(vertexCount == vertexMax) { 
      vertexMax = 2 * vertexMax; 
      vertexBuffer = realloc(vertexBuffer, vertexMax * 2 * sizeof(GLfloat)); 
     } 

     vertexBuffer[2 * vertexCount + 0] = start.x + (end.x - start.x) * ((GLfloat)i/(GLfloat)count); 
     vertexBuffer[2 * vertexCount + 1] = start.y + (end.y - start.y) * ((GLfloat)i/(GLfloat)count); 
     vertexCount += 1; 
    } 

    //Render the vertex array 
    glVertexPointer(2, GL_FLOAT, 0, vertexBuffer); 
    glDrawArrays(GL_POINTS, 0, vertexCount); 

    //Display the buffer 
    [context presentRenderbuffer:GL_RENDERBUFFER_OES]; 
} 

(該功能是基於從GLPaint樣品應用相同的名稱的功能) 對於我的壽命,我可以不知道爲什麼這會導致屏幕閃爍。該線條正確繪製(無論是在模擬器和iPod中)。但是,閃光燈使其無法使用。

任何人都有如何防止「閃光燈」的想法?

回答

1

經過多次測試,我找到了解決此問題的方法,但我不確定這是否是最佳做法。

解決方法是將kEAGLDrawablePropertyRetainedBacking從NO更改爲YES。這停止了​​閃爍。具體而言,編碼設置OpenGL的觀點現在看起來是這樣的:

CAEAGLLayer *eaglLayer = (CAEAGLLayer*) self.layer; 
eaglLayer.opaque = YES; 
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: 
           [NSNumber numberWithBool:YES], 
           kEAGLDrawablePropertyRetainedBacking, 
           kEAGLColorFormatRGB565, kEAGLDrawablePropertyColorFormat, nil]; 

同樣,我不知道,如果是使用RetainedBacking戰略的一個最佳實踐,但它停止閃爍。根據http://developer.apple.com/iphone/library/documentation/iPhone/Reference/EAGLDrawable_Ref/EAGLDrawable/EAGLDrawable.html#jumpTo_6,只有在某些情況下,才應將RetainedBacking設置爲YES。

只有當您需要內容保持不變時才建議將該值設置爲YES,因爲使用它可能會導致性能下降和額外的內存使用量。

目前尚不清楚性能或內存如何受到影響,但這一改變完全阻止了我所看到的所有「閃爍」。

+0

這幾乎絕對不是正確的解決方案。你只是掩蓋了這個問題。我也經歷了這一次,最初得出了同樣的結論。 – 2010-03-13 16:52:59

0

我有一次完全相同的問題。 我有一個UIWindow,我在其中放置了一個OpenGLES UIView。 繪圖過程很好,直到我試圖在OpenGLES視圖中添加一個子視圖(UIImageView)。屏幕閃爍。 我能夠通過添加UIImageView作爲UIWindow的子視圖來解決問題。 看來OpenGLES渲染不喜歡子視圖...

在OpenGLES

所以查看,如果你有這樣的:

[自我addSubView:...]

你可以取代它舉例來說,通過:

[self.superview addSubView:...]

不能在你的代碼中看到,如果你有類似的東西,但我希望這將有助於有點...:)

0

是否有可能您正在調用glRenderBuffer()並將presentRenderBuffer消息發送到您的EAGLContext而未執行任何OpenGL更新,即沒有新的glDrawElements或glDrawArrays。也許你正在代碼中的另一處發送presentRenderBuffer消息?如果您在沒有將kEAGLDrawablePropertyRetainedBacking設置爲YES的情況下執行此操作,則可能會出現惱人的閃爍。

看看你的CAEAGLLayer的drawableProperties屬性上的kEAGLDrawablePropertyRetainedBacking。該屬性確定了可繪製表面在顯示其內容後的行爲。如果此屬性設置爲NO,則內容不會保留,因此不能保證在顯示後保持不變。如果將其設置爲YES,則內容將保留並在顯示後保持不變。

我認爲將kEAGLDrawablePropertyRetainedBacking設置爲YES會掩蓋問題,但無法解決問題。