OpenGL 作为一个图形接口,并没有包含窗口的相关内容,但OpenGL使用必须依赖窗口,即必须在窗口中绘制。这就要求我们必须了解一种窗口系统,但不同的操作系统提供的创建窗口的API都不相同,如果我们在学习OpenGL时要去学习一整套的窗口系统,这将带来很多的不便,所以出现了GLUT。GLUT全称OpenGL Utility Toolkit,是一套和窗口系统无关的软件包,为我们提供了窗口创建,用户输入输出处理等功能。优点是:简小,精悍。注意GLUT并不是一个功能特别全面的窗口系统工具包,所以构建大型应用的时候还是需要根据需求选择相应的本机窗口系统工具包。
FreeGLUT
GLUT现有两个发行版:freeglut和原始版本的glut。原始glut的更新并没有随着opengl的发展而保持更新,所以本实践中采用的是freeglut。
GLUT的基本流程包括四步:
1)初始化GLUT库;
2)创建GLUT窗口;
3)注册display()回调函数;
4)进入GLUT主循环;
示例:
#include <iostream> #include <GLUT/freeglut.h>//freeGLUT窗口库 /** * 渲染回调函数 */ void Render(){ // 清空颜色缓存 glClear(GL_COLOR_BUFFER_BIT); // 交换前后缓存 glutSwapBuffers(); } /** * 主函数 */ int main(int argc, char ** argv) { // 初始化GLUT glutInit(&argc, argv); // 显示模式:双缓冲、RGBA glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); // 窗口设置 glutInitWindowSize(640, 480); // 窗口尺寸 glutInitWindowPosition(100, 100); // 窗口位置 glutCreateWindow("GLUT Window"); // 窗口标题 // 开始渲染 glutDisplayFunc(Render); // 缓存清空后的颜色值 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // 通知开始GLUT的内部循环 glutMainLoop(); return 0; }
glut初始化
在使用glut之前,一定要初始化glut库。函数原型为:
void glutInit(int argc,char **argv);
接下来可设置glut的一些属性。
配置显示特性
void glutInitDisplayMode(unsigned int mode);
mode 默认为GLUT_INDEXGLUT_SINGLE、GLUT_DEPTH的按位组合。
配置OpenGL版本
void glutInitContextVersion(int majorVersion, int minorVersion);
配置创建的上下文信息
void glutInitContextProfile(int profile)
core版本:GLUT_CORE_PROFILE;
兼容性版本:GLUT_COMPATIBILITY_PROFILE;
创建窗口
int glutCreateWindow(char* name);
设置窗口位置和大小
void glutInitWindowSize(int width,int height);
void glutInitWindowPosition(int x, int y);
设置渲染函数
void glutDisplayFunc(void (*func)(void));
窗口变化回调函数
void glutReshapeFunc(void (*func)(int width, int height));
键盘按键事件监听
void glutKeyboardFunc(void (*func)(unsigned char key, int x, int y));
void glutKeyboardUpFunc(void (*func)(unsigned char key, int x, int y));
鼠标事件监听
void glutMouseFunc(void (*func)(int button, int state, int x, int y)); //鼠标被按下是触发
void glutMotionFunc(void (*func)(int x, int y));//按下鼠标按钮并在窗口内移动触发
void glutPassiveMotionFunc(void (*func)(int x, int y));//鼠标指针在窗口内移动
窗口重绘标记
void glutPostRedisplay(void);标记窗口需要重绘,在下一次的执行过程中,将调用渲染函数。
背景管理
void glutIdleFunc(void (*func)(void));//当没有其它事件需要处理时的时候调用func,典型应用如动画
事件循环
void glutMainLoop();//永远不会返回