青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

xiaoguozi's Blog
Pay it forword - 我并不覺的自豪,我所嘗試的事情都失敗了······習慣原本生活的人不容易改變,就算現狀很糟,他們也很難改變,在過程中,他們還是放棄了······他們一放棄,大家就都是輸家······讓愛傳出去,很困難,也無法預料,人們需要更細心的觀察別人,要隨時注意才能保護別人,因為他們未必知道自己要什么·····

1. OpenGL 渲染管線

OpenGL渲染管線分為兩大部分,模型觀測變換(ModelView Transformation)投影變換(Projection Transformation)。做個比喻,計算機圖形開發就像我們照相一樣,目的就是把真實的場景在一張照相紙上表現出來。那么觀測變換的過程就像是我們擺設相機的位置,選擇好要照的物體,擺好物體的造型。而投影變換就像相機把真實的三維場景顯示在相紙上一樣。下面就分別詳細的講一下這兩個過程。

1.1模型觀測變換

讓我們先來弄清楚OpenGL中的渲染管線。管線是一個抽象的概念,之所以稱之為管線是因為顯卡在處理數據的時候是按照一個固定的順序來的,而且嚴格按照這個順序。就像水從一根管子的一端流到另一端,這個順序是不能打破的。先來看看下面的圖1:

1                     圖1 OPENGL渲染管線                                 

圖中顯示了OpenGL圖形管線的主要部分,也是我們在進行圖形編程的時候常常要用到的部分。一個頂點數據從圖的左上角(MC)進入管線,最后從圖的右下角(DC)輸出MC是Model Coordinate的簡寫,表示模型坐標DCDevice Coordinate的簡寫,表示設備坐標。 當然DC有很多了,什么顯示器,打印機等等。這里DC我們就理解成常說的屏幕坐標好了。MC當然就是3D坐標了(注意:我說的3D坐標,而不是世界坐 標),這個3D坐標就是模型坐標,也說成本地坐標(相對于世界坐標)。MC要經過模型變換(Modeling Transformation)才變換到世界坐標,圖2:

2圖2 世界坐標系和模型坐標系

變換到世界坐標WC(World Coordinate)說簡單點就是如何用世界坐標系來表示本地坐標系中的坐標。為了講得更清楚一些,這里舉個2D的例子。如圖3:

3 圖3 世界坐標系和模型坐標系的計算

圖中紅色坐標系是世界坐標系WC,綠色的是模型坐標系MC。現在有一個頂點,在模型坐標系中的坐標為(1,1),現在要把這個模型坐標轉換到世界坐標中來表示。從圖中可以看出,點(1,1)在世界坐標系中的坐標為(3,4),現在我們來通過計算得到我們希望的結果。首先我們要把模型坐標系MC在世界坐標系中表示出來,使用齊次坐標(Homogeneous Coordinate )可以表示為矩陣(注意,本教程中使用的矩陣都是以列向量組成):gif.latex 其中,矩陣的第一列為MC中x軸在WC中的向量表示第二列為MC中y軸WC中的向量表示第三列為MC中的原點在WC中的坐標。對齊次坐標系不了解的同學,請先學習游戲數學方面的知識。有了這個模型變換矩陣后,用這個矩陣乘以在MC中表示的坐標就可以得到該坐標在世界坐標系中的坐標。所以該矩陣和MC中的坐標(1,1)相乘有:

gif.latex2 這也正是我們需要的結果。現在讓我們把相機坐標也加進去,相機坐標也稱為觀測坐標(View Coordinate),如圖4和圖5。

4 圖4 ModelView變換的三個坐標系

5 圖5 ModelView變換計算

來看看MC坐標中的點(1,1)如何在相機坐標中表示。從圖5中可以直接看出MC中的點(1,1)在相機坐標系VC中為(-2,-2)。和上面同樣的道理,我們可以寫出相機坐標系VC在世界標系WC中可以表示為:

gif.latex3 那么世界坐標系中的點轉換為相機坐標系中的點我們就需求VC的逆矩陣:

gif.latex4那么世界坐標系WC中的點(3,4)在相機坐標系VC中坐標為:

gif.latex5 上面的變換過程,就是可以把模型坐標變換為相機坐標。在OpenGL中,當我們申明頂點的時候,有時候說的是世界坐標,這是因為初始化的時候世界坐標系、模型坐標系和相機坐標系是一樣的,重合在一起的。所以OpenGL中提供了模型觀測變換,它是把模型坐標系直接轉換為相機坐標系,如圖4。現在我們已經計算得到了VC-1和MC,如果把VC-1和 MC相乘,就可以得到模型坐標在相機坐標中的表示。為了得到模型坐標系中的坐標在相機坐標系中的表示,這就是OpenGL中的ModelView變換矩 陣。這也是ModelView變換的名字的由來,它是通過了上面兩個步驟得到的。那么這里,ModelView變換矩陣M為:

gif.latex6 現在只要用上面的模型觀測矩陣M乘以模型坐標系MC中的坐標就可以得到相機坐標系中的坐標了。模型觀測變換的關鍵就是要得到相機坐標系中的坐標,因為光照等計算都是在這個這個坐標系中完成的。下面我們實際OpenGL程序中檢查一下。在程序中,為了計算方便,我們使用圖6中的模型。

6 圖6 ModelView變換計算模型

根據圖中的數據,我們分別可以寫出對應MC和VC-1,從而求得觀測變換矩陣M

gif.latex7 現在程序中用glGetFloatv()這個函數來獲得當前矩陣數據來檢查一下。

  1. float m[16] = {0}; //用來保存當前矩陣數據  
  2. glMatrixMode(GL_MODELVIEW);  
  3. glLoadIdentity();  
  4. glGetFloatv(GL_MODELVIEW_MATRIX, m);   
  5. //相機設置,View 變換  
  6. gluLookAt(0.0, 0.0, 5.0,  
  7. 0.0, 0.0, 0.0,  
  8. 0.0, 1.0, 0.0);  
  9. glGetFloatv(GL_MODELVIEW_MATRIX, m);   
  10. //投影設置  
  11. glMatrixMode(GL_PROJECTION);  
  12. glLoadIdentity();  
  13. glOrtho(-10,10,-10,10,-10,10);  
  14. glMatrixMode(GL_MODELVIEW);   
  15. //Modeling變換  
  16. glTranslatef(0, 0, -3);  
  17. glGetFloatv(GL_MODELVIEW_MATRIX, m);  
  18. glBegin(GL_POINTS);  
  19. glVertex3f(1,1,0);  
  20. glEnd();  

如果在上面程序段中最后一個glGetFloatv(GL_MODELVIEW_MATRIX, m)處設定斷點的話,就可以看到圖7所顯示的數據。

7 圖7 ModelView變換矩陣數據

到這里,整個ModelView變換就完成了。通過ModelView變換后得到是相機坐標系內的坐標。在這個坐標系內典型的計算就是法線了。現在再來看看后面一個階段。

1.2投影變換

先還是復習一下OpenGL的渲染管線。圖1中可以看到,在投影變換(Projection Transformation)中也分為兩個部分,第一個部分是將上個階段得到的坐標轉換為平面坐標,第二個部分是將轉換后的平面坐標在進行歸一化并進行剪裁。一般地,將三維坐標轉換為平面坐標有兩種投影方式:正交投影(Orthogonal Projection)和透視投影(Perspective Projection)

1.2.1 正交投影

正交投影很簡單,如圖8,對于三維空間中的坐標點和一個二維平面,要在對應的平面上投影,只需將非該平面上的點的坐標分量改為該平面上的坐標值,其余坐標不變。

8 圖8 正交投影

比如將點(1,1,5)正交投影到z=0的平面上,那么投影后的坐標為(1,1,0)。在openGL中,設置正交投影可以使用函數:

  1. glOrtho (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)  

該函數可以設置正交投影的投影空間,在該空間以外的坐標點就不會被投影到投影平面上。函數中的六個參數分是投影空間六個平面,如圖9:

9

圖9 OpenGL正交投影空間和投影變換

在圖9中,大的投影空間是根據這六個參數設置的投影空間,OpenGL會自動將該空間歸一化,也就是將該空間或立方體轉化為變長為1的正六面體投影 空間,并且該證六面體的中心在相機坐標系的原點。一旦設置使用glortho函數設置投影空間,OpenGL會生成投影矩陣。這個矩陣的作用就是將坐標進 行正交投影并且將投影后的坐標正規化(轉換到-1到1之間)。要注意的是,生成該矩陣的時候,OpenGL會把右手坐標系轉換為左手坐標系。原因很簡單, 右手坐標系的Z軸向平面外的,這樣不符合我們的習慣。該矩陣的矩陣推導這里就不詳細說明了,不了解的同學可以參考游戲數學方面資料,這里只給出正交投影矩 陣。

15 這個矩陣看來很復雜,其實計算很簡單。舉個例子,現在設置了這樣的正交投影空間glOrtho(-10,10,-10,10,-10,10),這是個正六面體空間,變長為10。把這些參數帶入上面的矩陣可以得到

gif.latex8 現在還是在OpenGL程序中來檢查一下。在OpenGL程序中添加下面代碼段:

  1. //投影設置  
  2. glMatrixMode(GL_PROJECTION);  
  3. glLoadIdentity();  
  4. glOrtho(-10,10,-10,10,-10,10);  
  5. glMatrixMode(GL_MODELVIEW);  
  6. glGetFloatv(GL_PROJECTION_MATRIX,m)  
glGetFloatv(GL_PROJECTION_MATRIX,m)處設定斷點就可以看到圖10中所顯示的信息。

10 圖10 正交變換矩陣數據

1.2.2透視投影

透視投影和正交投影最大的區別就是透視投影具有遠近感。

11

圖11 透視投影

透視投影采用了圖11中的模型,這樣的模型就是保證遠的物體看起來小,近的物體看起來大。 在OpenGL中設置透視投影可以使用函數:

  1. void APIENTRY gluPerspective (GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);  

該函數也會根據給定的參數生成一個投影空間。如圖11中,該投影空間是一個截頭體。同樣地,OpenGL會自動生成透視投影矩陣,該矩陣也會讓3D坐標投影在投影平面上,并且將投影后的坐標也進行正規化。下面也直接給出OpenGL中使用的透視投影矩陣。

16 下面在OpenGL中添加下面代碼段:

  1. //投影設置  
  2. glMatrixMode(GL_PROJECTION);  
  3. glLoadIdentity();  
  4. gluPerspective(45, 1.0, 1.0, 100);  
  5. glMatrixMode(GL_MODELVIEW);  
  6. glGetFloatv(GL_PROJECTION_MATRIX,m)  

設置斷點后,我們可以看到圖12中顯示的數據。

12圖12 透視變換矩陣數據

到此為止,整個投影變換就完成了。透過投影變換后得到的是正規化的投影平面坐標。這為下一個階段的視口變換(View port Transformation)做好了準備。

1.3視口變換

現在到了最后一個階段了。這個階段叫做視口變換,它把上個階段得到的正規化的投影坐標轉化為windows 窗口坐標。視口變換會將投影平面上的畫面映射到窗口上。在OpenGL中可以使用函數

  1. GLAPI void GLAPIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);  

來進行對窗口的映射,如圖13。

13
圖13 視口變換glViewport(width/2, 0, width/2, height/2)

舉個例子說明,比如上個階段中得到了一個頂點的坐標為(0,0,0.5,1),根據這個坐標,該頂點位于投影平面的正中間。如果將該點映射到大小為 50*50的窗口上時,那么它應該位于屏幕的中間,坐標為(25,25, 0.5,1)。當然這里深度值0.5是不會改變的。有的同學肯定有疑問了,既然投影到了窗口上,那么還要深度值0.5干什么?這里要注意的是,雖然在窗口 上顯示時只需要x,y坐標就夠了,但是要在2D窗口上顯示3D圖形時深度值是不可少的。這里的深度值不是用于顯示,而是用于在光柵化的時候進行深度測試。

OpenGL也會根據glViewport函數提供的參數值生成一個視口變換矩陣

17 該矩陣把上個階段得到的正規化坐標映射到窗口上,并且將正規化坐標中的深度值在轉換到0到1之間。所以在深度緩沖中最大值為1,最小值為0。視口變換結束 后,OpenGL中主要的圖形管線階段就算完成了,后面就是光柵化等等操作。再來回顧一下圖1,現在相信大家對這個渲染管線有了一定的認識了,也明白了每 一個階段對應的變換矩陣以及如何進行坐標之間的轉換的。

2. 屏幕坐標轉換為世界坐標

通過前面的教程,以及現在大家對OpenGL整個渲染管線理解后,現在要將屏幕上一點坐標轉換為世界坐標就比較容易了。從圖形管線的開始到結束,一 個模型坐標系中的坐標被轉化為了屏幕坐標,那么現在把整個過程倒過來的話,屏幕上一點坐標也可以轉為為世界坐標。只要在對應的階段求得對應變換矩陣的逆矩 陣,就可以得到前一個階段的坐標。這整個過程可以用圖14表示。

14 圖14屏幕坐標轉換為世界坐標

圖中顯示的過程完全就是OpenGL渲染管線的逆過程,通過這個過程,屏幕上的點就可以轉化為世界坐標系中的點了。可能又有的同學要問,當鼠標點擊屏幕上一點的時候并沒有深度信息,轉換的時候要怎么辦呢?這個時候可以使用OpenGL函數

  1. void glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);  

該函數能夠獲得屏幕上一點對應像素的深度信息。有了這個深度信息,就可以利用上面過程把屏幕上一點轉換為世界坐標了。在OpenGL中,上面的過程其實已經有現成的函數可以使用,那就是

  1. int APIENTRY gluUnProject (  
  2.     GLdouble  winx, GLdouble  winy,  
  3.     GLdouble  winz,  
  4.     const GLdouble modelMatrix[16],  
  5.     const GLdouble projMatrix[16],  
  6.     const GLint    viewport[4],  
  7.     GLdouble  *objx,  GLdouble  *objy,  
  8.     GLdouble       *objz);  

該函數直接將屏幕上一點轉換對應的世界坐標,該函數的內部實現其實還是上面的那么逆過程。下面給出利用該函數獲取世界坐標的代碼段。

  1. GVector screen2world(int x, int y)  
  2. {  
  3.        GLint viewport[4];  
  4.        GLdouble modelview[16];  
  5.        GLdouble projection[16];  
  6.        GLfloat winX, winY, winZ;  
  7.        GLdouble posX, posY, posZ;  
  8.        glGetDoublev(GL_MODELVIEW_MATRIX, modelview);  
  9.        glGetDoublev(GL_PROJECTION_MATRIX, projection);  
  10.        glGetIntegerv(GL_VIEWPORT, viewport);  
  11.        winX = (float)x;  
  12.        winY = (float)viewport[3] - (float)y;  
  13.        glReadPixels(x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);  
  14.        gluUnProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);  
  15.        GVector v(4, posX, posY, posZ, 1.0);  
  16.        return v;  
  17. }  
代碼中函數返回類型GVector是用戶定義的向量類,返回的是齊次坐標。
posted on 2012-12-07 20:40 小果子 閱讀(1302) 評論(0)  編輯 收藏 引用 所屬分類: 學習筆記游戲開發
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲免费在线播放| 久久riav二区三区| 国内精品久久国产| 欧美成人视屏| 欧美精彩视频一区二区三区| 免费中文日韩| 欧美激情一区三区| 国产精品久久看| 国产伦精品一区| 国产区在线观看成人精品| 国产亚洲精品资源在线26u| 国产亚洲综合在线| 在线成人亚洲| 日韩亚洲欧美综合| 香蕉久久夜色精品| 久久美女艺术照精彩视频福利播放| 久久视频一区二区| 亚洲精品国产精品国自产在线| 久久精品国产精品 | 中文国产亚洲喷潮| 午夜精品99久久免费| 久久久久国产精品一区| 欧美精品日韩www.p站| 国产精品亚洲综合久久| 亚洲国产一区二区精品专区| 亚洲桃花岛网站| 久久综合久久久久88| 99精品视频一区二区三区| 欧美一区二区在线| 欧美激情精品久久久久| 国产精品稀缺呦系列在线| 亚洲经典自拍| 亚洲一区二区少妇| 一区二区三区欧美成人| 欧美一区二区三区免费大片| 免费国产自线拍一欧美视频| 亚洲天堂网在线观看| 欧美丰满少妇xxxbbb| 国产亚洲视频在线| 亚洲一区三区在线观看| 亚洲第一天堂av| 久久国产精品黑丝| 国产精品欧美日韩一区二区| 亚洲精品日韩一| 久久午夜影视| 亚洲欧美日韩天堂一区二区| 欧美激情一区二区三区在线视频观看| 国户精品久久久久久久久久久不卡| 夜夜嗨网站十八久久| 美女国产一区| 欧美中文在线观看国产| 国产女人18毛片水18精品| 亚洲视频一区二区| 亚洲国产精品热久久| 久久精品人人做人人爽电影蜜月| 欧美日韩亚洲一区三区 | 亚洲激情在线观看视频免费| 久久精品视频导航| 国产日韩欧美三级| 午夜精品久久久久久久99黑人| 亚洲国产日本| 欧美日韩国产欧美日美国产精品| 亚洲精品一区二区三区在线观看| 久久人体大胆视频| 欧美一二三视频| 国产一区二区三区久久久久久久久 | 在线亚洲美日韩| 欧美人妖在线观看| 在线亚洲精品| 一区二区三区精品国产| 欧美网站在线| 亚洲欧美激情视频在线观看一区二区三区| 99国产精品久久久久久久成人热| 欧美精彩视频一区二区三区| 99国产精品视频免费观看一公开 | 亚洲一区二区毛片| 日韩视频在线观看国产| 欧美日韩一二三四五区| 午夜精品久久久久久久久久久| 亚洲男女自偷自拍图片另类| 国产在线拍偷自揄拍精品| 最新中文字幕一区二区三区| 亚洲三级电影全部在线观看高清| 亚洲国产高清一区| 亚洲欧洲精品一区二区三区不卡 | 欧美精品久久久久久久久老牛影院 | 国产精品国产一区二区| 亚洲欧美美女| 羞羞色国产精品| 一区二区三区在线观看欧美| 欧美+日本+国产+在线a∨观看| 欧美96在线丨欧| 亚洲一区中文| 久久久久欧美| 一区二区不卡在线视频 午夜欧美不卡在| 日韩视频永久免费| 国产女优一区| 欧美激情日韩| 国产丝袜一区二区| 亚洲社区在线观看| 亚洲精品日韩一| 国产精品女主播在线观看| 欧美精品国产一区| 亚洲一区二区三区在线视频| 亚洲一区二区久久| 狠狠色综合色区| 亚洲国产高清在线观看视频| 国产精品色婷婷| 免费黄网站欧美| 国产乱码精品一区二区三区av| 欧美激情第六页| 国产日韩精品一区二区浪潮av| 亚洲国产成人av| 韩国亚洲精品| 亚洲一区不卡| 中国亚洲黄色| 欧美不卡在线| 久久综合图片| 国产一区二区三区免费不卡| 亚洲天堂男人| 中文av一区二区| 牛夜精品久久久久久久99黑人| 久久成人18免费观看| 国产精品久久久久久超碰 | 久久精品免费| 性欧美精品高清| 亚洲网站视频| 久久精品日产第一区二区三区| 性色av香蕉一区二区| 欧美日韩在线播| 裸体歌舞表演一区二区| 国产日韩一级二级三级| 亚洲欧美综合| 国产一区二区视频在线观看| 一区二区三区在线免费视频| 久久国产黑丝| 激情另类综合| 亚洲永久视频| 亚洲人成在线观看一区二区| 久久精品国产视频| 亚洲欧美激情视频| 国产精品超碰97尤物18| 欧美激情视频一区二区三区免费| 在线观看国产日韩| 亚洲精品日韩在线观看| 亚洲日韩视频| 欧美激情一区二区三区不卡| 欧美 日韩 国产精品免费观看| 伊人成人在线视频| 欧美专区日韩视频| 久久亚洲国产精品一区二区| 国产精品麻豆成人av电影艾秋| 亚洲第一福利视频| 国产精品美女久久久久久免费 | 久久久99精品免费观看不卡| 亚洲激情图片小说视频| 国产一级揄自揄精品视频| 午夜精品久久久久久久99热浪潮 | 亚洲国产另类久久精品| 韩国精品在线观看| 久久九九久精品国产免费直播 | 老司机亚洲精品| 欧美高清视频一区| 另类图片综合电影| 亚洲无限av看| 欧美激情成人在线视频| 亚洲一区二区三区乱码aⅴ| 亚洲一区不卡| 国产婷婷色一区二区三区四区| 亚洲欧美文学| 老司机精品视频网站| 在线精品视频免费观看| 欧美日韩国产黄| 99精品视频免费观看视频| 久久久精品免费视频| 国内精品**久久毛片app| 亚欧成人精品| 欧美影院视频| 国产精品影院在线观看| 欧美成人网在线| 国产精品一区亚洲| 免费观看成人网| 国产精品久久久久久久久动漫| 欧美韩日一区| 久久不射2019中文字幕| 99国产麻豆精品| 欧美一区二区性| 韩国精品一区二区三区| 欧美日韩国产精品成人| 日韩午夜剧场| 欧美成人精品| 亚洲一区二区三区乱码aⅴ蜜桃女| 国产人成精品一区二区三| 久久精品成人一区二区三区| 亚洲精品日韩精品| 欧美va亚洲va国产综合| 欧美亚洲日本网站| 在线亚洲欧美视频| 国内精品福利| 国产精品久久久久久av下载红粉|