2010-10-25 52 views
7

我對這一點有點困惑。OpenGL ES 2.0多重網格? (只是真實世界的例子)

我在書籍,博客,論壇甚至OpenGl規範中發現的一切都只是談論一種非常抽象的技術。沒有關於真實世界的例子。

我對此很瘋狂:如何使用OpenGL ES 2.x來放置和管理多個對象(網格)?

理論上看起來很簡單。你有一個頂點着色器(vsh)和片段着色器(fsh),然後你將它們綁定到一個程序(glGenProgram,glUseProgram,...)。在渲染的每個循環中,該程序將通過每個頂點執行其VSH,然後在該3D對象的每個「像素」上執行FSH,並最終將最終結果發送到緩衝區(顯然不用談論每個頂點,柵格化和管道中的其他步驟)。

OK,看似簡單...

這一切都是通過向繪製函數(調用glDrawArrays或glDrawElements)的調用解僱。

再次確定。

現在事情來困惑我。 並且如果你有幾個對象要渲染?

讓我們來談談一個真實世界的例子。假設你有一個樹木和一個角色的景觀。 景觀的草地有一種紋理,樹木對樹幹和樹葉具有紋理(紋理圖集),最後該角色具有另一種紋理(紋理圖集)並且也是動畫。

想象一下這個場景後,我的問題很簡單: 你怎麼組織這個?

您爲場景中的每個元素創建一個單獨的程序(帶有一個VSH和FSH)?就像一個草地和土壤的救濟計劃,一個樹木計劃和一個計劃的性格?

我試過了,但是...當我創建多個程序並嘗試使用glVertexAttribPointer()時,對象的紋理和顏色與對方發生衝突。因爲在第二個程序中重複第一個程序的屬性(索引)的位置。

讓我解釋一下,我在一個控制場景底部的類中使用了glGetAttribLocation(),所以OpenGL核心向我返回了頂點屬性的索引0,1和2。 之後,在樹的類中我創建了另一個程序,另一個着色器,並且此後再次使用了glGetAttribLocation(),此時OpenGL核心返回索引爲0,1,2和3.

在渲染循環中,我開始用glUseProgram()設置第一個程序,並使用glVertexAttribPointer()更改了它的頂點屬性,最後調用了glDrawElements()。之後,再次調用glUseProgram()到第二個程序並再次使用glVertexAttribPointer(),最後再使用glDrawElements()。 但此時,事物進入衝突,因爲第二個程序的頂點屬性索引也會影響第一個程序的頂點。

我嘗試了很多東西,搜索了很多,問了很多...我累死了。我找不到有什麼問題。

所以我開始認爲我做錯了一切!

現在我再次重複我的問題:如何在OpenGL ES 2.x中使用多個網格(使用不同的紋理和行爲)?使用多個程序?怎麼樣?

回答

0

謝謝回答,

但我認爲你只是在重複我自己的話......關於繪圖方法,大約一個積極的計劃,一切。

無論如何。

重點是你的話給我一個洞見! 你說過:「你需要重置所有的頂點屬性和指針」。

嗯......沒有完全重置,但我沒有更新渲染週期中的所有頂點屬性,如紋理座標。我正在更新那些改變的屬性。當我清除緩衝區時,我丟失了較舊的值。

現在我開始更新所有屬性,獨立於變化或不是它們的值,一切正常!

知道,我收到的是:

glCreateProgram(); 
... 
glAttachShader(); 
glAttachShader(); 
... 
glLinkProgram(); 
glUseProgram(); 
... 
glGetAttribLocation(); 
glVertexAttribPointer(); 
glEnableVertexAttribArray(); 
... 
glDrawElements(); 

我反覆的過程,以第二方案,而只是調用glVertexAttribPointer()幾次。

現在,我所擁有的是對所有屬性的glVertexAttribPointer()調用。

讓我瘋狂的是,如果我把第一塊代碼移到第一個程序,整個第二程序運行良好。 如果我將第二個代碼塊刪除到第二個程序,第一個代碼就可以正常工作。

現在看起來很明顯。 當然,如果VSH是每頂點操作,如果我不更新所有屬性和制服,它將使用零值。 我雖然關於OpenGL更像一個3D引擎,與3D對象一起工作,有一個場景,你放置你的對象,設置燈光。但是,不... OpenGL只是知道三角形,線條和點,只不過是。我現在覺得不同了。

無論如何,重點是現在我可以前進!

謝謝

+0

請問你好嗎?我很高興你明白:D – MatterGoal 2013-04-21 21:41:57

2

要繪製多個網格,只需調用glDrawElements/glDrawArrays多次。如果這些網格需要不同的着色器,只需設置它們。 ONE,並且只有一個着色器程序處於活動狀態。

因此,每次更改着色器程序(特別是VS)時,都需要重置所有頂點屬性和指針。

就這麼簡單。