日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OpenGL编程指南7:视图-

發布時間:2025/3/15 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenGL编程指南7:视图- 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.前言

計算機圖形學的要點就是創建三維物體的二維圖像(圖像必須是二維的,因為他是在平面的屏幕上顯示的)。但是,當我們決定怎樣在屏幕上繪圖時,必須使用三維坐標的方式考慮。 為了把一個物體的三維坐標變成屏幕上的像素坐標,需要完成以下三個步驟:
  • 變換包括模型、視圖和投影操作,這是通過矩陣乘法表示的。這些操作包括:旋轉、移動、縮放、反射、正投影和透視投影等。一般情況下,在繪制場景時,需要組合幾種變換。
  • 由于場景是在一個矩形窗中渲染的,因此位于窗口之外的物體(或物體的一部分)必須裁減掉。在三維計算機圖形學中,剪裁就是丟棄位于裁剪平面之外的物體。
  • 經過了變換之后的坐標屏幕像素之間必須建立對應關系,這個過程就是視口變換
視圖和模型變換一起構成了模型視圖矩陣,這個矩陣作用于物體坐標,產生視覺坐標。接著,如果還指定了其他裁剪平面,用于從場景中刪除某些物體或者提供物體的裁剪視圖,這些裁剪平面就會在此時生效。 頂點變換的流程如下圖所示:
OpenGL采用投影矩陣來完成剪裁坐標,這個變換定義了一個視景體,位于這個空間之外的物體將裁剪掉,不會在最終的場景中出現。 隨后發生的是透視除法,他把坐標除以w,產生規范化的設備坐標 最后,變換后的坐標通過視口變換成窗口坐標,可以通過控制視口的大小對最終的圖像進行放大、縮小或拉伸。

2.詳細理解各個變換

1. 一個例子

#include <vgl.h>void init(void) {glClearColor(0.0,0.0,0.0,0.0);glShadeModel(GL_FLAT); } void display(void) {glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0,1.0,1.0);glLoadIdentity();gluLookAt(0.0,0.0,5.0,0.0,0.0,0.0, 0.0,1.0,0.0);glScalef(1.0,2.0,1.0);glutWireCube(1.0);glFlush(); } void reshape(int w, int h) {glViewport(0,0,(GLsizei)w,(GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity();glFrustum(-1.0,1.0,-1.0,1.0,1.5,20.0);glMatrixMode(GL_MODELVIEW); } int main(int argc, char** argv) {glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);glutInitWindowSize(500,500);glutInitWindowPosition(100,100);glutCreateWindow(argv[0]);init();glutDisplayFunc(display);glutReshapeFunc(reshape);glutMainLoop();return 0; }輸出結果:

2.2 視圖變換

視圖變換相當于把照相機固定在三腳架上并使它對準場景。上面例子中,在指定視圖變換之前,需要使用glLoadIndentity()函數將當前矩陣設置為單位矩陣,這一步是非常必要的!!!因為絕大多數的變換是將當前矩陣與指定的矩陣相乘,然后把結果指定為當前矩陣。如果沒有通過加載單位矩陣來清除當前矩陣,它所進行的變換實際上是把當前的變換與上一次變換進行組合。當然啦,在某些情況確實需要這種組合變換,但是大多數情況下,還是要清除當前矩陣的。 上例中,先進行矩陣初始化,然后使用glLookAt()函數指定了視圖變換。這個函數實際上就是眼睛/照相機的位置、瞄向以及朝上方向。void gluLookAt(GLdouble eyeX , GLdouble eyeY , GLdouble eyeZ , //相機位置GLdouble centerX , GLdouble centerY , GLdouble centerZ , //相機焦點GLdouble upX , GLdouble upY , GLdouble upZ ); //相機向上方向
gluLookAt(0.0,0.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0);這里設定的參數是把攝像機放在了(0,0,5)的位置;鏡頭瞄準(0,0,0);朝向為(0,1,0);需要注意的是朝上向量為攝像機指定了唯一的方向。 Attention!!! 如果沒有調用gluLookAt()函數,那么攝像機就會采用默認的位置和方向。默認情況下,照相機位于原點,指向z軸的負方向,朝上向量為(0,1,0);

2.3 模型變換

模型變換的目的是設置模型的位置和方向。可以對模型進行旋轉、移動和縮放等操作。上例僅采用了縮放這個參數。 void glScalef(GLfloat x, GLfloat y, GLfloat z); //縮放。參數指定在那個方向上縮放 void glTranslatef(GLfloat x, GLfloat y, GLfloat z); //移動。 void glRotatef(GLfloat angle, GLfloat x,GLfloat y,GLfloat z); //從原點到點(x,y,z)的直線進行旋轉的角度。

2.3 投影變換

投影變換的目的在于確定視野,并因此確定那些物體位于視野之內以及他們能夠被看到的程度和攝像機非常類似,好比選擇廣角鏡頭、標準鏡頭還是長焦鏡頭。使用廣角鏡頭的場景范圍要遠大于長焦鏡頭。但是長焦鏡頭可以使遠處的物體看上去比實際更靠近相機。 除了視野,投影變換還決定物體是如何投影到屏幕上的。OpenGL提供了兩種基本類型的投影。其一是透射投影,另一種是正投影
  • 透射投影
void glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearVal, GLdouble farVal);參數分別指定了垂直裁剪平面的左右位置、水平裁剪平面的上下位置以及相機離深度裁剪平面的近、遠距離。
glFrustrum定義了一個平截頭體,它計算一個用于實現透視投影的矩陣,并把它與當前的投影矩陣(一般為單位矩陣)相乘。
Attention!!! 平截頭體并不要求一定是對稱的,它的軸也不需要與Z軸對齊。
glFrustrum使用起來不是很直觀,我們可以用OpenGL工具函數庫的gluPerspective函數。
void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);參數fovy表示眼睛張開的角度。 aspect表示縱橫比x/y。 zNear和zFar分別表示觀察者離近遠裁剪平面的距離。
注意:gluPerspective僅限于創建沿視線方向同時對稱與x軸和y軸的平截頭體。
但是我們通常所需要的也就是這種平截頭體。
  • 正投影
void glOrtho( GLdouble left,GLdouble right,GLdouble bottom,GLdouble top,GLdouble nearVal,GLdouble farVal);創建一個正交平行的視景體。參數和glFrustrum一樣。
如果是把二維圖像投影到二維屏幕這種情況,可以使用OpenGL工具函數庫中的gluOrtho2D函數。它與它的三維版本glOrtho基本相同。
Attention!!! 在調用glFrustum()或glOrtho()設置透視投影或者正投影之前,需要做一些準備工作 首先,需要以GL_PROJECTION為參數調用glMatrixMode()函數,表示把當前矩陣指定為用于偷用變換。 然后,設置投影矩陣初始化為單位陣。 接著,設定采用透射投影還是正投影。 最后,以GL_MODELVIEW為參數再次調用glMatrixMode()函數,表示以后的變換所影響的是模型視圖矩陣而不再是投影矩陣。
glMatrixMode(GL_PROJECTION); //開始投影變換glLoadIdentity();//glFrustum(-1,1.0,-1,1,1.5,5.5); //透視變換glOrtho(-1,1.0,-5,5,0.5,20); //正投影glMatrixMode(GL_MODELVIEW); //結束投影變換轉到視圖變換Attention!!! 上例中,reshape()函數同時包括投影變換和視口變換。
當窗口初次創建時,或者當窗口移動或改變形狀時,reshape()函數都會被調用。這是很合理的,因為投影(投影視景體的寬度-高度縱橫比)和視口都是與屏幕直接相關的,特別是與屏幕窗口的大小或縱橫比直接相關。

2.4 視口變換

投影變換和視口變換共同決定了場景是如何映射到計算機屏幕的。投影變換指定了投影的發生機制,而視口變換則決定了場景所映射的有效屏幕區域的形狀。由于視口指定了場景在屏幕上所占據的區域,因此,可以吧視口變換看成是定義了最終經過處理的照片的大小和位置。例如,照片是否應該放大或者縮小。void glViewport(GLint x, GLint y, GLsizei width, GLsizei height); //設置視口及像素將要顯示的區域。(注意(0,0)表示窗口的左下角) glViewport()參數描述了窗口內部有效屏幕空間的遠點。上例中為(0,0)。另外,該函數也描述了有效屏幕區域的寬度與高度。該函數需要在reshape()函數內部調用,用于響應窗口的變化。

2.5 繪制場景

指定了視圖-模型變換、投影-窗口變換后就可以繪制場景了。在繪制場景時,OpenGL通過模型和視圖變換對場景中每個物體的每個頂點進行變換。然后,根據指定的投影變換對每個定點進行變換。如果頂點位于視景體之外,就會被裁剪掉。最后剩余的頂點除以W,然后映射到視口中。

3.參考資料

[1] 施萊爾, GrahamSellers, JohnKessenich,等. OpenGL編程指南[M]. 機械工業出版社, 2014.

總結

以上是生活随笔為你收集整理的OpenGL编程指南7:视图-的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。