opengl基礎知識 關於四個變換的順序

OpenGL中的gl庫是核心庫,glu是實用庫,glut是實用工具庫,

gl是核心,glu是對gl的部分封裝,glut是OpenGL的跨平臺工具庫,gl中包含了最基本的3D函數,而glu似乎對gl的輔助,如果算數好,不用glu的情況下,也是可以做出同樣的效果。

glut是基本的窗口界面,是獨立於gl和glu的,如果不喜歡用glut可以用MFC和Win32窗口等代替,但是glut是跨平臺的,這就保證 了我們編出的程序是跨平臺的,如果用MFC或者Win32只能在windows操作系統上使用。選擇OpenGL的一個很大原因就是因爲它的跨平臺性,所 以我們可以儘量的使用glut庫。



一個典型的opengl程序:

#include <GL/glut.h>  
#include <stdlib.h>
#include<stdio.h>

/*
g++ main.cpp camera.cpp -Iinclude -lGL -lglut -lGLU
*/
static int shoulder = 0, elbow = 0;  
static int nearplane=1;
Camera camera;
   float dxx=0.1;
   float dyy=-0.2;
void init(void)   
{  
   glClearColor (0.0, 0.0, 0.0, 0.0);  
   glShadeModel (GL_FLAT);  
}  
  void display(void)  
{  
   glClear (GL_COLOR_BUFFER_BIT);  
     glPushMatrix();//保存的是單位矩陣  
     glTranslatef (0.0, 0.0, -5.0);
     glTranslatef (1.0, 0.0, 0.0);
   glutWireCube (1.0);  
  glPopMatrix();
  glutSwapBuffers(); 
    
}  
void reshape (int w, int h)  
{  
   glViewport (0, 0, (GLsizei) w, (GLsizei) h);  
   glMatrixMode (GL_PROJECTION);  
   glLoadIdentity ();
   
   gluPerspective(65.0, (GLfloat) w*1/(GLfloat) h, nearplane, 20.0);  
   glMatrixMode(GL_MODELVIEW);  
   glLoadIdentity();
   
   //glTranslatef (0.0, 0.0, -5.0);  
}  
  
void keyboard (unsigned char key, int x, int y)  
{  
    static int angle=5;  
   switch (key) {
        case 'w':
        // nearplane = (nearplane+1) % 18; 
        // glMatrixMode (GL_PROJECTION);
        //  glLoadIdentity ();  
        // gluPerspective(65.0, 1, nearplane, 20.0);  
      
        
         glutPostRedisplay();
         printf("nearplane %d\n",nearplane);
         break;  
      case 27:  
         exit(0);  
         break;
        
      default:  
         break;  
   }  
}  
  
int main(int argc, char** argv)  
{  
   glutInit(&argc, argv);  
   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);  
   glutInitWindowSize (500, 500);   
   glutInitWindowPosition (100, 100);   
   glutCreateWindow (argv[0]);  
   init ();  
   glutDisplayFunc(display);   
   glutReshapeFunc(reshape);  
   glutKeyboardFunc(keyboard);  
   glutMainLoop();  
   return 0;  
} 

display函數是每一幀都需要調用的回調函數, reshape是窗口發生變化時的需要調用的回調函數,

reshape在一開始窗口創建的時候也會被調用,這裏涉及的是opengl的四個矩陣變換,由調用順序 ,viewport projection view model,分別是視口:主要控制投影出的二維平面如何在窗口中顯示;投影變換:控制三維圖像如何投影到二維平面;視點變換:控制觀察點(眼睛)的位置,向上的方向,觀察的方向;模型變換,包括位移和旋轉。在實際中這些變換的順序是和代碼中調用順序是相反的,這也符合我們的現實的直觀的感受。

glMatrixMode() 

如果參數是GL_PROJECTION,這個是投影的意思,就是要對投影相關進行操作,也就是把物體投影到一個平面上,就像我們照相一樣,把3維物體投到2維的平面上。這樣,接下來的語句可以是跟透視相關的函數,比如glFrustum()或gluPerspective();

如果參數是GL_MODELVIEW,這個是對模型視景的操作,接下來的語句描繪一個以模型爲基礎的適應,這樣來設置參數,接下來用到的就是像gluLookAt()這樣的函數;

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(...);
//這裏最好先調用glPushMatrix()
//下面就可以任意調用glTranslate*(),glRotate*(),glScale*()等函數了,注意如果再次調用了glLoadIdentity(),則需要重新調用gluLookAt()
//也就是說,如果讓gluLookAt()函數調用達到想要的效果的話,gluLookAt()設置的矩陣一定是模型視圖矩陣所乘的第一個矩陣,且最多乘一次



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章