我希望有人可以幫我指明瞭一些紋理基準我做的OpenGL ES 2.0的一些進展和iPhone 4優化OpenGL ES 2.0的2D紋理輸出和幀率
我有一個包含精靈的數組對象。渲染循環遍歷每個紋理的所有精靈,並檢索其所有紋理座標和頂點座標。它使用退化的頂點和索引將它們添加到一個巨大的交織陣列中,並將它們發送給GPU(我嵌入的代碼是底部)。這一切都是按照紋理完成的,所以我將紋理綁定一次,然後創建我的交錯數組,然後繪製它。一切都很好,屏幕上的結果正是他們應該做的。
因此,我的基準測試是通過在不同的不透明度下添加25個新的精靈,並在更新上更改它們的頂點,以便在應用程序上旋轉並運行OpenGL ES分析器時,它們在屏幕周圍彈跳。
繼承人,我希望有一些幫助.... 我可以達到約275個32x32精靈與不同的不透明度在60 fps的屏幕上跳動。到400我下降到40幀/秒。當我運行OpenGL ES Performance Detective時,它會告訴我...
應用程序渲染受三角形柵格化的限制 - 將三角形轉換爲像素的過程。所有正在渲染的三角形的總面積(以像素爲單位)太大。要以更快的幀率繪製,請通過減少三角形的數量,其大小或兩者的大小來簡化場景。
的是我剛颳起了測試在cocos2d使用CCSpriteBatchNode使用相同的紋理和創建800個透明精靈和幀率爲60fps的容易。
下面是一些代碼,可能是中肯......
Shader.vsh(矩陣在成立伊始一次)
void main()
{
gl_Position = projectionMatrix * modelViewMatrix * position;
texCoordOut = texCoordIn;
colorOut = colorIn;
}
Shader.fsh(colorOut用於calc下不透明度)
void main()
{
lowp vec4 fColor = texture2D(texture, texCoordOut);
gl_FragColor = vec4(fColor.xyz, fColor.w * colorOut.a);
}
VBO設置
glGenBuffers(1, &_vertexBuf);
glGenBuffers(1, &_indiciesBuf);
glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuf);
glBufferData(GL_ARRAY_BUFFER, sizeof(TDSEVertex)*12000, &vertices[0].x, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(TDSEVertex), BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(TDSEVertex), BUFFER_OFFSET(8));
glEnableVertexAttribArray(GLKVertexAttribColor);
glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, sizeof(TDSEVertex), BUFFER_OFFSET(16));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indiciesBuf);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(ushort)*12000, indicies, GL_STATIC_DRAW);
glBindVertexArrayOES(0);
更新代碼
/*
Here it cycles through all the sprites, gets their vert info (includes coords, texture coords, and color) and adds them to this giant array
The array is of...
typedef struct{
float x, y;
float tx, ty;
float r, g, b, a;
}TDSEVertex;
*/
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuf);
//glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertices[0])*(start), sizeof(TDSEVertex)*(indicesCount), &vertices[start]);
glBufferData(GL_ARRAY_BUFFER, sizeof(TDSEVertex)*indicesCount, &vertices[start].x, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
渲染代碼
GLKTextureInfo* textureInfo = [[TDSETextureManager sharedTextureManager].textures objectForKey:textureName];
glBindTexture(GL_TEXTURE_2D, textureInfo.name);
glBindVertexArrayOES(_vertexArray);
glDrawElements(GL_TRIANGLE_STRIP, indicesCount, GL_UNSIGNED_SHORT, BUFFER_OFFSET(start));
glBindVertexArrayOES(0);
下面有在400只小精靈(三角形800 800 +退化三角形)的屏幕截圖,得到不透明分層作爲紋理被移動的一個想法... 再次,我應該注意的是,一個VBO正在創建和發送每個紋理,所以我綁定,然後每幀只繪製兩次(因爲只有兩個紋理)。
很抱歉,如果這是壓倒性的,但在這裏它的我的第一篇,想徹底。 任何幫助將不勝感激。
PS,我知道我可以使用Cocos2D而不是從頭開始編寫所有的東西,但是在那兒玩的樂趣(和學習)?!
UPDATE#1 當我我的片段着色器切換到僅是
gl_FragColor = texture2D(texture, texCoordOut);
它到達802個在精靈50fps的(4804三角形包括退化三角形),儘管設置子畫面不透明度丟失..任何建議到如何仍然可以在我的着色器中處理不透明度而不以1/4的速度運行?
UPDATE#2 因此,我放棄了GLKit的View和View控制器,並編寫了一個從AppDelegate加載的自定義視圖。 902不透明的精靈& 60fps的透明度。
與其使用OpenGL ES Performance Detective,我更喜歡使用帶有OpenGL ES分析器和OpenGL ES驅動程序工具的儀器。分析器通常會指出更細微的渲染問題,並且驅動程序可以在Tiler(頂點側)和Renderer(片段側)爲您提供百分比負載,以驗證您的瓶頸位置。另外嘗試運行Time Profiler對此。這看起來比應該慢,因爲我把A4的基準定爲1。使用VBOs和簡單的陰影,每秒800萬個三角形,或以60 FPS在屏幕上約30000個三角形。 – 2012-03-20 20:07:13
感謝回覆@BradLarson。儘管有些事情我不太瞭解... Renderer Utiliz:99%,Tiler Utilz:8%,Device Utilz:99%,我儘可能使用Analyzer和Driver。思考? Analyzer中唯一突出的是多餘的調用,但絕大多數來自glView(綁定幀緩衝區等)。 Time Profilier顯示83%來自我綁定和更新VBO(在更新中完成)並繪製。你認爲使用glView是問題的一部分嗎?我認爲這是transp層(即時貼上截圖和我更新的代碼)。謝謝。 – yiannis 2012-03-20 21:23:27
如果您的渲染器利用率確實爲99%,而您的鋪磚機爲8%,那麼顯然您的填充率受限,而不是幾何形狀受限。優化三角形和你的VBO不會對你有什麼好處,你需要專注於繪製更少的像素或更快地繪製像素。你已經在上面的場景中進行了很多混合,[來自經驗](http://stackoverflow.com/q/6051237/19679)如果一堆混合對象堆積在一起,我知道這是非常昂貴的彼此頂部。您可以渲染不透明區域並寫入深度緩衝區,然後在混合半透明區域時從中讀取。 – 2012-03-21 14:43:29