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()設置的矩陣一定是模型視圖矩陣所乘的第一個矩陣,且最多乘一次