2011-04-08 68 views
6

我對使用OpenGL中的紋理三角形網格繪製全屏幕背景時看到的糟糕表現感到困惑:只繪製背景而沒有其他東西在使用最基本的着色器爲40 fps,使用默認管道爲50 fps。全屏幕背景紋理與OpenGL性能問題(iPad)

雖然40 fps看起來並不算太差,但是在其上添加其他任何東西都會使fps下降,並且考慮到我需要在其上繪製100-200個其他網格物體,最終會得到微小的15 fps這根本不可用。

我已經分離的相關代碼到可用的XCode項目here,但它的本質是規範的紋理貼圖例如:

static const GLfloat squareVertices[] = { 
    -1.0f, -1.0f, 
    1.0f, -1.0f, 
    -1.0f, 1.0f, 
    1.0f, 1.0f, 
}; 
static const GLfloat texCoords[] = { 
    0.125, 1.0, 
    0.875, 1.0, 
    0.125, 0.0, 
    0.875, 0.0 
}; 


glClearColor(0.5f, 0.5f, 0.5f, 1.0f); 
glClear(GL_COLOR_BUFFER_BIT); 

if ([context API] == kEAGLRenderingAPIOpenGLES2) { 
    // Use shader program. 
    glUseProgram(program); 

    glActiveTexture(GL_TEXTURE0); 
    glUniform1i(uniforms[UNIFORM_TEXTURE], 0); 
    glBindTexture(GL_TEXTURE_2D, texture); 

    // Update attribute values. 
    glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices); 
    glEnableVertexAttribArray(ATTRIB_VERTEX); 
    glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, texCoords); 
    glEnableVertexAttribArray(ATTRIB_TEXCOORD); 
} else { 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    glEnable(GL_TEXTURE_2D); 
    glBindTexture(GL_TEXTURE_2D, texture); 
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 

    glVertexPointer(2, GL_FLOAT, 0, squareVertices); 
    glEnableClientState(GL_VERTEX_ARRAY); 
    glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
} 

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

頂點着色器:

attribute lowp vec4 position; 
attribute lowp vec2 tex; 

varying lowp vec2 texCoord; 

uniform float translate; 

void main() 
{ 
    gl_Position = position; 
    texCoord = tex; 
} 

片段着色器:

varying lowp vec2 texCoord; 
uniform sampler2D texture; 

void main() 
{ 
    gl_FragColor = texture2D(texture, texCoord); 
} 

將矩形大小除以2渲染時間明顯地取決於繪圖在屏幕上顯示的房地產。這是完全合理的,但對我來說沒有意義的是,用OpenGL紋理映射網格覆蓋整個屏幕看起來不可能超過15 fps。

然而,有數百款遊戲可以做到這一點,所以這是可能的,我必須做出錯誤的事情,但它是什麼?

+0

FWIW,您爲什麼在撥打相關電話後啓用客戶端狀態的任何原因? (例如,在啓用vert數組之前調用頂點指針) – 2011-04-08 15:21:29

+0

實際上,大多數代碼都來自OpenGL ES iPad應用程序的默認模板,這並不意味着它是很好的代碼,但只要它有效,我就不會問自己無論這種或那種方式是否有意義:-) – 2011-04-08 16:47:16

回答

7

不幸的是,我現在所擁有的就是我的iPad 2來測試它(我的iPad 1測試裝置坐在家裏),並且它具有快速的碎片處理能力。它被固定在60 FPS,在你的測井中有1400理論FPS。但是,我使用OpenGL ES驅動程序和Time Profiler儀器以及酷炫的新型OpenGL ES分析器(隨Xcode 4一起提供)在儀器上運行。這是從的OpenGL ES分析的結果如下:

OpenGL ES Analyzer

綜觀了OpenGL ES驅動鋪放器使用率統計顯示幾乎被所有使用的瓦工,但有一些使用的渲染器(再次,在我的iPad 2上只有5%)。這表明對於幾何體使用VBOs和索引的建議可能對您沒有太大幫助。

那伸出的一個是關於冗餘呼叫警告:

OpenGL ES redundant calls

你留着結合幀緩存和設置視每一幀,而根據時間探查器佔10%工作負載在您的應用程序。註釋掉靠近你的框架拉制開始行

[(EAGLView *)self.view setFramebuffer]; 

引起了理論幀率跳從1400 FPS 27000 FPS在我的iPad 2(順便說一句,你應該measure using milliseconds for your rendering)。

再次,這是我在iPad 2上運行真正強大的GPU的測試,但您應該能夠在原始iPad或任何其他設備上重複這些類似步驟來驗證此性能瓶頸並可能突出顯示其他設備。我發現新的OpenGL ES分析器在處理與着色器相關的性能問題時非常方便。

+0

「不幸的是,我所擁有的就是我的iPad 2,現在就測試它」。我想和你一樣不幸:-)感謝您將測試應用程序放在iPad 2上!我從你的回答中看出,你看我畫背景的方式沒有錯? – 2011-04-08 16:48:12

+0

@Guy - 我剛剛在我現在已經過時的iPad 1上試用了這款產品,而且我仍然獲得60 FPS,即使在刪除上面的多餘呼叫之前,該舊硬件上的理論FPS也是1400。在你的Xcode構建設置中可能會有些問題,因爲你的測試用例在我的硬件上運行的速度非常快。此外,這是在該硬件上使用iOS 4.3.1。如果你使用3.2,可能會變慢。 – 2011-04-09 00:47:50

+0

感謝一堆爲了理智檢查,我會進一步調查! – 2011-04-10 09:18:57

0

胡亂猜測下面,我沒有任何的iPad體驗:根據本benchmark

,你可以期望有關於純填充率214fps,在背景的分辨率。

您是否嘗試禁用紋理,檢查您是否受到紋理的限制?

你的質感是「兩種質感的非功率」嗎?在這種情況下,您是否嘗試從GL_TEXTURE_WRAP_*中刪除GL_REPEAT,替換爲GL_CLAMP(_TO_EDGE)?重複NPOT可能會在某些硬件上花費一些性能。

最終,您可以嘗試將最小/最大過濾器設置爲GL_NEAREST。

+0

圖片沒有2維度的權力,但我加載到一個512x512紋理,我也試過GL_NEAREST,但不是GL_CLAMP。會做,感謝指針。 – 2011-04-10 09:21:40