一、实验原理
1、OpenGL程序框架
#include <GL/freeglut.h>
void init(){
/* 全局初始化。主要用于设置一些全局的状态,如颜色模式、
窗口的初始位置和大小等。使用默认值时不需要定义该函数。*/
}
void init2(){
/* 当前窗口初始化。主要用于设置一些与当前窗口关联的状态或开关,如光照处理、
光源特性、深度检测和裁剪等。使用默认值时不需要定义该函数。*/
}
void Reshape(int w, int h){
/* 设置投影方式和观察体。主要使用glViewport()、glOrtho()、glFrustum()、
gluPerspective()和gluOrtho2D()等。使用默认值时不需要定义该函数。*/
}
void Paint(){
/* 使用OpenGL库函数构造对象的数学描述,包括点线面的位置、
几何变换和光照处理等,是OpenGL的主要部分。*/
}
int main(int argc, char *argv[]){
glutInit(&argc, argv); // 初始化GLUT, 记录main()的参数
init(); // 全局初始化, 使用默认值时不是必需的
glutCreateWindow("窗口标题"); // 创建程序窗口,指定窗口标题
init2(); // 当前窗口初始化, 使用默认值时不是必需的
// 注册回调函数
glutDisplayFunc(Paint); // 指定场景绘制函数,必需
glutReshapeFunc(Reshape); // 指定窗口变化回调函数,缺省则使用默认值
glutMainLoop(); // 开始循环执行OpenGL命令
}
2、OpenGL部分函数说明
(1)初始化GLUT库:void glutInit(int *argc, char **argv);
(2)设置窗口的初始大小:void glutInitWindowSize(int width, int height);
(3)进入GLUT事件处理循环:void glutMainLoop(void);
(4)注册窗口变化回调函数:void glutReshapeFunc(void (*func)(int width, int height));
(5)注册场景绘制函数:void glutDisplayFunc(void (*func)(void));
(6)清除颜色缓冲区:void glClear(GL_COLOR_BUFFER_BIT);
(7)指定背景颜色:void glClearColor(float red, float green, float blue, float alpha);
(8)结束绘图并返回:void glFlush(void);
(9)基本图元定义的开始:void glBegin(GLenum mode);
(10)基本图元定义的结束:void glEnd(void);
(11)消除其他视口中的物体变换对当前视口的影响:void glLoadIdentity();
(12)将物体绕旋转轴(0,0,0)~(x,y,z) 旋转th度以调整物体的方向:void glRotatef(GLfloat th, GLfloat x, GLfloat y, GLfloat z);
3、基本图元部分预定义几何形体
(1)矩形:void glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2);
(2)立方体:
① 实心立方体:void glutSolidCube(GLdouble size);
② 线框立方体:void glutWireCube(GLdouble size);
(3)球面:
① 实心球面:void glutSolidSphere(GLdouble radius, int slices, int stacks);
② 线框球面:void glutWireSphere(GLdouble radius, int slices, int stacks);
(4)犹他茶壶:
① 实心立方体:void glutSolidTeapot(GLdouble size);
② 线框立方体:void glutWireTeapot(GLdouble size);
二、算法程序
1、使用OpenGL和GLUT编写一个显示线框球体的简单图形程序。其中球体半径为0.8,经线数为24,纬线数为12,并绕x轴旋转30度,程序窗口的大小为(200,200),标题为“线框球”;
#include <GL/glut.h>
void Paint() {
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glRotated(30, 1, 0, 0);
glutWireSphere(0.8, 24, 12);
glFlush();
}
int main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutInitWindowSize(200, 200);
glutCreateWindow("线框球");
glutDisplayFunc(Paint);
glutMainLoop();
return 0;
}
2、使用OpenGL、GLU和GLUT编写一个显示线框立方体的程序。其中立方体的半径为1.5单位,并首先绕(0, 0, 0)~(1, 1, 0)旋转30度,然后远移6.5单位;观察体规定为:视场角=30度,宽高比=1,近=1,远=100;程序窗口的大小为(200, 200),标题为“线框立方体”。
#include <GL/glut.h>
void Paint() {
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
gluPerspective(30, 1, 1, 100);
glTranslatef(0, 0, -6.5);
glRotated(30, 1, 1, 0);
glutWireCube(1.5);
glFlush();
}
int main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutInitWindowSize(200, 200);
glutCreateWindow("线框立方体");
glutDisplayFunc(Paint);
glutMainLoop();
return 0;
}
3、使用OpenGL、GLU和GLUT编写一个三维犹他茶壶程序。其中茶壶的半径为1单位,并远移6.5单位;观察体规定为:视场角=30度,宽高比=1,近=1,远=100;程序窗口的大小为(200, 200),标题为“旋转的犹他茶壶”。茶壶绕z方向中轴不断旋转,旋转的时间间隔为25毫秒,角度间隔为2度。注意旋转角度必须限定在0~360度以内。
#include <GL/glut.h>
int angle = 0;
void Paint() {
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
gluPerspective(30, 1, 1, 100);
glTranslatef(0, 0, -6.5);
glRotated(angle, 0, 0, 1);
glutSolidTeapot(1);
glFlush();
}
void timer(int millis){
angle = (angle + 2) % 360;
glutPostRedisplay();
glutTimerFunc(millis, timer, millis);
}
int main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutInitWindowSize(200, 200);
glutCreateWindow("旋转的犹他茶壶");
glutTimerFunc(25, timer, 25);
glutDisplayFunc(Paint);
glutMainLoop();
return 0;
}
三、结果演示
1、线框球
2、线框立方体
3、旋转的犹他茶壶