2009-10-28 25 views
16

我有一些編寫OpenGL 2應用程序的經驗,並希望學習使用OpenGL 3.爲此,我購買了Addison Wesley的「紅皮書」和「橙皮書」(GLSL),其中描述了固定的棄用功能和新的可編程管道(着色器)。但是我無法理解的是,如何構建一個包含多個對象的場景,而不使用已過時的translate *,rotate *和scale *函數。如何翻譯OpenGL 3.x中的單個對象?

我以前在OGL2中做的事情是使用translate和rotate函數在3D空間中「移動」,並使用glBegin ... glEnd在本地座標中創建對象。在OGL3中,這些函數都被棄用,並且據我所知,被着色器取代。但是我無法爲我製作的每個對象調用shaderprogram,對嗎?這不會影響所有其他對象嗎?

我不知道如果我解釋了我的問題令人滿意的,但它的核心是如何用在OpenGL 3.1本地座標定義多個對象的場景編程。我發現的所有初學者教程只使用一個對象,並沒有/解決這個問題。

編輯:想象一下,你想要兩個旋轉的立方體。這將是一個痛苦手動修改每個頂點座標,並不能簡單地修改模型視圖矩陣,因爲那寧可旋轉攝像頭圍繞兩個靜態立方體...

回答

20

讓我們從基礎開始。

通常情況下,你想通過下面的步驟來改變你的本地三角形頂點:

local-space coords-> world-space coords -> view-space coords -> clip-space coords

在標準GL,第2個變換通過GL_MODELVIEW_MATRIX完成,第三個是通過GL_PROJECTION_MATRIX

完成

這些模型視圖轉換對於我們通常要應用的許多有趣變換(例如,平移,縮放和旋轉等)來說,在我們用表示頂點時碰巧可以表示爲矢量矩陣乘法。典型地,頂點V = (x, y, z)在該系統中被表示爲(x, y, z, 1)

好的。假設我們想通過翻譯轉換頂點V_local,然後是旋轉,然後是翻譯。每個變換可以表示爲矩陣*,我們稱它們爲T1,R1,T2。 我們希望將變換應用於每個頂點:V_view = V_local * T1 * R1 * T2。矩陣乘法是關聯的,我們可以一勞永逸計算M = T1 * R1 * T2

這樣,我們只需要將M傳遞給頂點程序,並計算V_view = V_local * M。最後,典型的頂點着色器將頂點位置乘以單個矩陣。計算一個矩陣的所有工作都是如何將對象從本地空間移動到剪輯空間。

好的...我瞥了一些重要的細節。

首先,我到目前爲止所描述的只是真正涵蓋了我們通常希望做的視圖空間轉換,而不是剪輯空間。但是,硬件期望頂點着色器的輸出位置在該特殊的剪輯空間中表示。在沒有重要數學的情況下,很難解釋片段空間座標,所以我會將其忽略,但重要的一點是,將頂點引入該片段空間的變換通常可以表示爲相同類型的矩陣乘法。這是舊的gluPerspective,glFrustum和glOrtho計算的結果。

其次,這是你應用於頂點的位置。改變法線的數學有些不同。這是因爲你希望法線在變換之後保持垂直於表面(作爲參考,它在一般情況下需要乘以模型視圖的逆轉置,但在很多情況下可以簡化)

第三,你永遠不會向頂點着色器發送四維座標。一般來說,你會通過3D。 OpenGL會將這些三維座標(或二維,btw)轉換爲四維座標,以便頂點着色器不必添加額外的座標。它展開每個頂點以添加1作爲w座標。

所以......把所有的東西放在一起,對於每個對象,你需要根據你想要應用到對象的所有變換來計算這些魔術M矩陣。在着色器中,您必須將每個頂點位置乘以該矩陣,並將其傳遞給頂點着色器位置輸出。典型的代碼是多還是少(這是用舊的命名):

mat4 MVP; 
gl_Position=MVP * gl_Vertex; 

*實際矩陣可以在網絡上找到,特別是在手冊頁每個這樣的功能:rotatetranslatescaleperspectiveortho

+1

謝謝你的回答!我錯過的一個細節是你可以在調用glDrawElements之間改變MVP矩陣(例如聲明它是統一的)...... 奇怪的從khronos移動到離開這些非常常見的矩陣的規格給程序員。希望他們能很快找到他們的方式,或者類似的方式...... – Wonko 2009-10-28 22:37:01

+0

這就是中間件的用途。 GL3.2對於快速編碼的表現力較弱。但是以前的版本對於實際應用來說是錯誤的抽象層次。它需要一個國家管理框架。 另外,假設你想保持矩陣。這意味着驅動程序必須保留所有的矩陣堆棧,如何將它們僅傳遞給需要它的_all_着色器(不僅僅是頂點),找出你需要哪種味道--M,MV,MVP,IT(MV),IT(M )。最糟糕的部分?該應用程序是唯一一個可以通過一次運行多個矩陣操作來提高數學效率的應用程序。 GL無法做到這一點。 – Bahbar 2009-10-29 10:03:55

1

這些功能顯然過時了,但在技術上仍然完美的功能,實際上將編譯。所以你當然可以繼續使用translate3f(...)等功能。

然而,this tutorial已經很好地解釋了新着色器等等如何工作,以及如何處理空間中的多個對象。

您可以創建x個頂點數組,並將它們綁定到x個VAO對象中,然後使用着色器等從那裏渲染場景......呃,讀起來更容易 - 它是一個非常好的讀取掌握新概念。

此外,OpenGL'紅皮書',因爲它被稱爲有一個新的版本 - The Official Guide to Learning OpenGL, Versions 3.0 and 3.1。它包括「討論OpenGL的棄用機制以及如何驗證您的程序以適應未來版本的OpenGL」。

我希望這是一些幫助!

+0

再次感謝您的快速回答。我讀過你提到的教程,但是雖然他創建了兩個三角形,但他在全局座標中創建了它們 - 不是我想要的。問題是當你有一個更復雜的模型時,使用全局座標會很麻煩,特別是如果模型移動的話。另外,我想從.obj文件加載預製對象,並將其放置在3D空間中的某個位置。 – Wonko 2009-10-28 17:39:56

+8

@Mark第一個鏈接已損壞。 – Jeff 2012-11-29 06:00:01