亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Win32 OpenGL編程(9) 投影變換

系統 2115 0

 Win32 OpenGL編程(9) 投影變換  

 write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie        

 討論新聞組及文件        

提要

在前文(系列文章(7),以下簡稱XO7,系列其他文章類似)中的照相機比喻中提到了4種3D變換,如下:

1.確定照相機的位置的過程對應于“視圖變換”(Viewing Transformations)

2.確定物體位置的過程對應于“模型變換”(Modeling Transformations)

3.確定照相機放大倍數的過程對應于“投影變換”(Projection Transformations)

4.確定照片大小的過程對應于“視口變換”(Viewport Transformations)

XO7中我們講的是第一種變換視圖變換,即改變觀察者本身的位置,視角等的變換效果,XO8中講的是第二種變換模型變換,本文開始繼續按順序講解下一個3D變換過程,投影變換。

正投影

投影變換的過程就像是照相機選鏡頭的過程,目的是確定視野,其實說起來投影一詞,我在學習工程制圖的時候就接觸過了,不知道大家是否學過這門課程,工程制圖就是一種將三維空間的事物設想投影在二維空間中,然后畫下來,工程中應用非常廣泛,那時候學的那些剖面圖什么的,也是累死我了-_-!OpenGL就可以模擬這樣的過程,并且名字和工程制圖中的名字是一樣的,叫正投影。

OpenGL以glOrtho來指定一個正交平行的矩形,屏幕上顯示的就是此物體在此矩形的正面的投影。在XO2中用過的gluOrtho2D實際上是此函數的一個去掉Z軸坐標的簡化版,而glOrtho包括的參數nearVal,farVal表示此矩形的前,后兩面,超出此矩形范圍的圖形將會被裁掉。

《      OpenGL Programming Guide         》:

glOrtho — multiply the current matrix with an orthographic matrix      
  C Specification      
  void glOrtho( GLdouble left,      
  GLdouble right,      
  GLdouble bottom,      
  GLdouble top,      
  GLdouble nearVal,      
  GLdouble farVal);      
  Parameters

left, right

Specify the coordinates for the left and right vertical clipping planes.      
  bottom, top

Specify the coordinates for the bottom and top horizontal clipping planes.      
  nearVal, farVal

Specify the distances to the nearer and farther depth clipping planes.      
  These values are negative if the plane is to be behind the viewer.

用此函數,通過調整nearVal與farVal我們可以實現類似工程制圖中的剖面的效果,見下例:

  GLfloat gfNear = 1.0;      
    
    
 SceneShow(GLvoid)        
      
  {      
  
    glClear(GL_COLOR_BUFFER_BIT);      
  
    glColor3f(1.0, 0.0, 0.0);      
  
  
    glMatrixMode(GL_PROJECTION);      
  
    glLoadIdentity();      
  
    glOrtho(-1.0, 1.0, -1.0, 1.0, gfNear, -1.0);      
  
  
  
    glPushMatrix();      
  
    DrawSmoothColorPyramid(0.5);      
  
    glPopMatrix();      
  
  
    glFlush();      
  }  
      
  
    
  
    
 Game_Main(        
 *parms = NULL, 
        
 num_parms = 0)      
  {      
  
    DWORD dwStartTime;      
  
  
    dwStartTime = GetTickCount();      
    
    
  
    
    
 (KEYDOWN(VK_ESCAPE))      
  
        SendMessage(ghWnd,WM_CLOSE,0,0);      
  
    
 (KEYDOWN(VK_UP))      
  
    {      
  
        gfNear -= 0.01;      
  
    }      
  
    
 (KEYDOWN(VK_DOWN))      
  
    {      
  
        gfNear += 0.01;      
  
    }      
  
  
  
    SceneShow();      
  
  
    
    (GetTickCount() - dwStartTime < TIME_IN_FRAME)      
  
    {      
  
        Sleep(1);      
  
    }      
  
  
    
    (1);      
  
  }

 

以下就是當nearVal為0.8時的效果,也就是說,Z軸坐標大于0.8的,一律被截掉了,在工程制圖中,我們老師常將,此時假設在此用一刀將物體切掉。

上面的源代碼中還出現了一個新函數,glMatrixmode,用于指定以下的變換是針對哪個變換的,

glMatrixMode(GL_PROJECTION);

用于指定以下的變換是針對投影變換的,而用

glMatrixMode(GL_MODELVIEW);

方式調用時,(默認值)表示  針對模型變換。  

為節省篇幅僅貼出關鍵片段,完整源代碼見我博客源代碼的2008-10-28/glOrthoSample 目錄,獲取方式見文章最后關于獲取博客完整源代碼的說明。

 張軍博客  


 

透視投影

上述的正投影僅僅存在于想象之中,主要是工程制圖(或者CAD)中能夠正確反映物體的真實尺寸,現實中我們看東西,越遠的越小,越近的越大,并且所有物體最終會消失在遠方(地平線),OpenGL常用于VR(虛擬現實),這樣程度的視覺仿真效果自然是有的,在OpenGL中,這樣投影叫做透視投影。OpenGL提供了兩個函數用于指定透視投影,兩個函數僅僅是參數表示的方式不同,事實上效果是一樣的。

《      OpenGL Programming Guide         》:

glFrustum — multiply the current matrix by a perspective matrix      
  C Specification      
  void glFrustum( GLdouble left,      
  GLdouble right,      
  GLdouble bottom,      
  GLdouble top,      
  GLdouble nearVal,      
  GLdouble farVal);      
  Parameters

left, right

Specify the coordinates for the left and right vertical clipping planes.      
  bottom, top

Specify the coordinates for the bottom and top horizontal clipping planes.      
  nearVal, farVal

Specify the distances to the near and far depth clipping planes.      
  Both distances must be positive.

gluPerspective — set up a perspective projection matrix      
  C Specification      
  void gluPerspective( GLdouble fovy,      
  GLdouble aspect,      
  GLdouble zNear,      
  GLdouble zFar);      
  Parameters

fovy

Specifies the field of view angle, in degrees, in the y direction.      
  aspect

Specifies the aspect ratio that determines      
  the field of view in the x direction.      
  The aspect ratio is the ratio of x (width) to y (height).      
  zNear

Specifies the distance from the viewer to the near clipping plane      
  (always positive).      
  zFar

Specifies the distance from the viewer to the far clipping plane      
  (always positive).

事實上,glFrustum指定的方式與glOrtho很像,參數意義也一致,僅僅是使用后OpenGL使用的投影方式不同,gluPerspective函數指定的方式是模擬觀察者(照相機)的視角,用fovy指定觀察者的上下視角(及在y-z平面上觀察的角度),aspect指定觀察寬度與高度的比,然后用zNear指定離觀察者較近的截面,用zFar指定離觀察者較遠的截面(都指離觀察者的距離),下例展示了原來那個三角錐從遠方的一個小點然后到放大到原來大小的過程:

  GLfloat gfDis = 5.0;      
  
    
    
 SceneShow(GLvoid)        
      
  {      
  
    glMatrixMode(GL_PROJECTION);      
  
    glLoadIdentity();      
  
    glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 5.0);      
  
  
    glMatrixMode(GL_MODELVIEW);      
  
    glLoadIdentity();      
  
    gluLookAt(0.0, 0.0, gfDis, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0);      
  
  
    glClear(GL_COLOR_BUFFER_BIT);      
  
    glColor3f(1.0, 0.0, 0.0);      
  
  
    glPushMatrix();      
  
    DrawSmoothColorPyramid(0.5);      
  
    glPopMatrix();      
  
  
  
    glFlush();      
  }  
      
  
    
 Game_Main(        
 *parms = NULL, 
        
 num_parms = 0)      
  {      
  
    DWORD dwStartTime;      
  
  
    dwStartTime = GetTickCount();      
    
    
  
    
    
 (KEYDOWN(VK_ESCAPE))      
  
        SendMessage(ghWnd,WM_CLOSE,0,0);      
  
    
 (KEYDOWN(VK_UP))      
  
    {      
  
        gfDis -= 0.01f;      
  
    }      
  
    
 (KEYDOWN(VK_DOWN))      
  
    {      
  
        gfDis += 0.01f;      
  
    }      
  
  
    SceneShow();      
  
    
    (GetTickCount() - dwStartTime < TIME_IN_FRAME)      
  
    {      
  
        Sleep(1);      
  
    }      
  
    
    (1);      
  
  } // end Game_Main


 

上面例子中靠

gluLookAt(0.0, 0.0, gfDis, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0);

來調整觀察者的位置,通過上下鍵調節,會模擬出一種慢慢走近三角錐的過程,三角錐也是隨著走近由小慢慢變大。

實際上最重要的還是

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 5.0);

三句確定的透視投影方式。

 張軍博客  張軍博客  張軍博客  


 




為節省篇幅僅貼出關鍵片段,完整源代碼見我博客源代碼的2008-10-28/glPerspective 目錄,獲取方式見文章最后關于獲取博客完整源代碼的說明。

小結:

相對來說,個人認為投影變換是屬于OpenGL中重要但是確較難理解的一部分,動態變化上述函數的參數,準確理解上述函數中每個參數的意義是種不錯的學習途徑,其中Nate Robin的OpenGL教程有個很形象的教學程序。對應投影變換的教程為projection一例


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 免费视频爱爱太爽了 | 中国在线播放精品区 | 牛牛影院免费永久地址 | a成人在线 | 久久久久草 | 99热国产免费 | 九九夜夜 | 全部精品孕妇色视频在线 | 好吊妞在线播放 | 妖精视频永久在线入口 | 国产精品四虎视频一区 | 四虎最新永久免费视频 | 国内久久久久久久久久 | 一级毛片免费播放视频 | 爱爱免费观看高清视频在线播放 | 亚洲国产99在线精品一区69堂 | 手机看片福利盒子久久 | 亚洲欧美婷婷 | 亚洲综合在线观看视频 | 久久国产一区二区三区 | 日本xxxx色视频在线观看免 | 久久不见久久见免费影院 | 久久国产精品99久久久久久牛牛 | 99re热在线视频 | 亚洲精品香蕉一区二区在线观看 | 午夜一级毛片看看 | 99r8这里精品热视频免费看 | 狠狠操91| 四虎网站1515hh四虎免费 | 日本黄色免费一级片 | 亚洲酒色1314狠狠做 | 亚洲成a人伦理 | 性欧美video另类bd | 麻豆精品永久免费视频 | 四虎国产精品免费久久影院 | 亚洲第一区第二区 | 香蕉视频伊人 | 亚洲精品另类 | 毛片免费全部播放一级 | 四虎影视永久地址www成人 | 日韩一区二区三区不卡 |