最近在學習opengl的幾何變換,其中對幾何變換函數的作用範圍糾結了很久,這裏寫下心得與大家分享,共同學習。
參考資料:《opengl編程基礎(第三版)》第五章 幾何變換
對變換函數作用範圍的疑惑
- 平移:glTranslate
- 旋轉:glRotate
- 縮放:glScale
書上對於這些函數的描述都提到所有頂點
,如果是這樣的話,那我執行一個變換函數豈不是所有的圖元都會一起變換了,要怎麼實現只對特定圖元的變換呢?
解答: 變換函數作用範圍
使用
glPushMatrix();
//todo 這裏執行變換函數,以及圖元的繪製
glPopMatrix();
- 與3dmax、maya等三維軟件中我所理解的變換不同,opengl中的變換最終是作用於渲染的。
- 也就是說:先進行變換操作,然後再繪製圖元,這時所繪製的圖元會受到變換函數的影響。
- 書上提及
變換是作用於所有頂點的
可以這樣理解:變換函數作用於模型視圖矩陣,最終由模型視圖矩陣作用於圖元的渲染,只要模型視圖矩陣沒有被改變,這之後進行繪製的所有圖元都會受到該模型視圖矩陣的影響。
變換的順序受矩陣運算順序的影響
進行變換操作後再繪製圖元,矩陣的運算順序。請看下面這個例子:
變量 | 含義 |
---|---|
M | 模型視圖矩陣 |
模型視圖矩陣的初值,假設這裏是單位矩陣 | |
,, | 變換矩陣 |
V | 模型座標矩陣 |
- 首先,初始化模型視圖矩陣,
- 然後,程序依次執行了,,三個變換,此時 (變換矩陣是右乘到當前模型視圖矩陣上的)
- 最後,進行圖元的繪製,此時模型座標矩陣會右乘到模型視圖矩陣上,即 繪製時,其變換的順序是, 可以理解爲先跟V進行作用。
以下代碼爲display函數中的一部分:
glPushMatrix();
glTranslatef(0.0, TORSO_HEIGHT+0.5*HEAD_HEIGHT, 0.0);//平移1
glRotatef(theta[1], 1.0, 0.0, 0.0);//旋轉1
glRotatef(theta[2], 0.0, 1.0, 0.0);//旋轉2
glTranslatef(0.0, -0.5*HEAD_HEIGHT, 0.0);//平移2
drawObject();//繪製圖元,沒有任何變換的圖元
glPopMatrix();
opengl中每一幀都回調display函數,在display函數中根據當前幀的變換操作繪製圖元,這樣我們就看到了一個動態的變換操作。