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()设置的矩阵一定是模型视图矩阵所乘的第一个矩阵,且最多乘一次