2012-06-26 56 views
3

我是新來的OpenGL ES,我正在寫一個iPad應用程序,需要我加載一個波前OBJ文件,在OpenGL中繪製它們。我的問題是關於渲染Obj文件組的最有效方法。渲染的OBJ組在OpenGL ES

什麼我都有點背景。 Obj模型的所有解析/加載工作正常(我使用GLM加載文件),所以這些繁瑣的工作已經完成。對於基礎項目,我已經在XCode中擴展了OpenGL ES遊戲模板,並將所有調用移除到着色器中。我爲我的着色器使用GLKit的BaseEffect,並使用VAO和VBO加載我所有的頂點數據。對於一個有16個組的模型,在初始時我將每個組分成一個VAO,每個VAO有一個VBO用於頂點數據和法線(交錯),第二個VBO用於紋理座標。每個組都有一個材料(有時候是一個紋理,但是爲了這個問題只考慮材料)。在我的渲染例程(下面的僞代碼)中,我循環遍歷爲每個組創建的所有VAO,將組的材質應用到BaseEffect,然後使用DrawArrays繪製它(不使用DrawElements,因爲我'已經設置了VBO,所以數據已經處於索引順序,儘管它可能不如圖形內存那樣高效)。這是有效的,我可以用不同的材質繪製每個模型,但隨着組數的增加,我的幀速率下降,因爲我必須花費更多時間循環渲染函數中的每個組。對於較低的模型數量,這很好,但是當我爲應用添加更多模型時,幀速率遠低於30fps,這是我的基準。

for (groups in model) 
{ 
    Bind VAO for this group 

    Apply Material or Texture (if one exists) for this group using GLKBaseEffect 

    Call PrepareToDraw for GLKBaseEffect 

    DrawArrays passing it the vertex count for this group 

    glBindVertexArray(0) 
} 

顯而易見的答案是如此,有少組簡化模型,但我很好奇,如果有到渲染程序,可以讓我做同樣的事情,但不太繪製調用任何改進。我想仍然有一個詳細的obj文件,但也有最有效的渲染,我可以。

這是繪製OBJ文件在那裏我有在文件中使用多種材料/紋理每個組的最好的方法,或者是有沒有辦法這樣做需要通過每個組循環和單獨畫他們做些什麼呢?我希望能夠讓每個obj模型只有1個調用DrawArrays/DrawElements,但我不明白這是如何完成的,並且仍然將多個材質/紋理應用於該對象。我一直在看這個代碼,並且認爲「必須有更好的方法」,但是我不確定那是什麼。如果我錯過了一個明顯的難題,或者如果你有任何建議可以提供優化,我將永遠感激。

回答

3

我想你已經差不多有正確的想法。一次只能有一組紋理或一個着色器處於活動狀態,因此必須繪製使用該狀態的模型部分,切換狀態並繪製下一個組。

如果您添加更多型號的性能降低,你可以嘗試這樣你畫的所有連續相同狀態的羣體無需切換組進行排序。

所以,如果你正在繪製模型100份,模型有三組A,B和C:然後,而不是這樣做:

foreach(model) 
    set state A; 
    glDrawArrays(A); 
    set state B; 
    glDrawArrays(B); 
    set state C; 
    glDrawArrays(C); 

你應該做這樣的事情:

sort models into groups; 
foreach(group) 
    set state 
    foreach(instance of group) 
     glDrawArrays 

這樣可以節省你的狀態轉換的約99%(着色器開關,紋理結合,等等)。這將是一個很大的性能改進。

+0

感謝蒂姆。我會看一看,看看這是否會奏效。 – Baxpin

+0

這是有效的,除了在我的解決方案中,而不是將所有單獨的對象分成類似的組,我創建了我的VAO,對於單個對象,具有相同紋理/材質的所有組被合併到單個緩衝區中。這樣一個具有10個使用普通紋理的組的大對象將被繪製成1遍。換句話說,我不是基於在obj中定義的對象組構建我的VAO,而是基於它使用的材質構建它。效率不如Tim所描述的那麼高效,但類似,現在也能工作。 – Baxpin