"GLUT"[I] 全称为 OpenGL Utility Toolkit.[/I] Mark J. Kilgard 创作的 GLUT 库,
是我们创建完全独立于窗口系统的 OpenGL 程序成为可能. 感谢 GLUT, 我们能够在不了解 X Windows 或者 Microsoft Windows
窗口系统本身的情况下编写3D应用程序. Kilgard 编写了GLUT的 X Windows 版本, 后来, Nate Robins 又将之移植到
Microsoft Windows 系统之上. 谢谢你们二位, 你们完成了一项伟大的工作.
在这份教程里, 我将向你介绍一些关于编写
GLUT 应用程序的一些基础. 为了简单起见, 这片教程不会介绍复杂的视觉效果.
你需要什么?
首先, 你需要一份最新版本的
GLUT 库(在这份文档编写的时候, 我相信是 3.7版). 当你完成了这份基础教程后, 你可以在 GLUT主页 中,
你可以找到大量的实例.
通过 C语言编写 GLUT 程序, 你需要以下三个文件:
GLUT.H -
你需要在你的源代码中包含这个文件. 通常情况下, 这个文件应该放在你系统的包含目录下的 GL 文件夹中
GLUT.LIB (SGI
windows版本) 以及 glut32.lib (微软版本) - 这个文件必须被连接到你的程序中, 确保它放在 LIB 目录中
glut32.dll (Windows) 和 glut.dll (SGI Windows版本) - 根据你所使用的OpenGL选择一个,
如果你正在使用微软公司的版本, 那么你必须选择 glut32.dll. 你应该把DLL放置在你的系统文件夹中
设置Visual C/C++
6.0
Visual C/C++的工程有两个重要选项: Console (控制台) 和 Win32. 应用程序将会有两个窗口: 一个控制台窗口,
以及一个 OpenGL 窗口. 选择 Win32 仍然可以让你在不需要关心Windows程序设计的情况下编写 GLUT 程序. 你需要做以下设置:
选择 Project -> settings
选择 Link 选项卡
从 Category 中选择 Output
在 Entry-point synmbol 文本框中键入 mainCRTStartup
对于已存在的控制台工程,
有一个简单的办法将它转换成Win32应用程序:
根据上面的步骤修改入口点
在 Project options 文本框中用
subsystem:windows 覆盖 subsystem:console
或者你可以直接在你的源代码开头处添加:
代码
// #pragma comment( linker, "/subsystem:\"windows\"
/entry:\"mainCRTStartup\"" )
注意: 这是一行注释
如此一来,
应用程序就不会出现控制台窗口, 而只是一个 OpenGL 窗口了. 在Visual C/C++ 中你需要一下步骤来连接一个 GLUT 程序:
选择
Proejct/Settings
选择 LINK 选项卡
添加一下文件到 Object/library: opengl32.lib
glut32.lib glu32.lib
请注意: 我同时添加了glu32.lib 和 opengl32.lib.
他们是标准OpenGL库.
好的,现在一切准备就绪, 我们可以开始编写 GLUT 应用程序了. 如果有任何不清楚的地方, 请您告诉我,
您的回馈非常之重要.
在这一节中, 我们将会建造应用程序的主函数(main function).
主函数将会将会完成程序的初始化并启动事件处理循环. 所有函数都有一个前缀 glut , 初始化函数的前缀是 glutInit. 我们首先必须调用函数
glutInit.
代码
void glutInit(int *argc, char **argv);
//参数:
//argc - 一个指向主函数 argc 变量的 未经修改 的指针.
//argv - 一个指向主函数 argv
变量的 未经修改 的指针.
初始化 GLUT 本身以后, 我们将会定义我们的窗口. 首先, 我们建立窗口的位置, 例如:
在窗口的左上角. 要实现这个功能, 我们需要调用函数 glutWindowsPosition.
代码
void
glutInitWindowPosition(int x, int y);
//参数:
//x- 距离屏幕左边的像素数. 默认值是 -1,
由Windows系统决定窗口的位置. 如果没有没有采用默认值, 那么你应该使用一个合适正值作为实参.
//y- 距离屏幕屏幕顶端的像素数,
其余同上.
请注意, 这些参数只是给窗口管理器的一个建议值. 我们创建的窗口可能会处于不同的位置上, 不过这很少发生. 接下来我们要决定窗口的大小,
为了做到这一点, 我们需要使用函数 glutInitWindowSize.
代码
void
glutInitWindowSize(int width, int height);
参数:
width -
窗口的宽度
height - 窗口的高度
同样的, 高和宽也只是一个建议值,
请避免使用负值.
然后我们需要定义显示模式, 我们使用 glutInitDisplayMode 函数.
代码
void glutInitDisplayMode(unsigned int mode)
参数:
mode -
指定显示模式
//mode 参数是一个 GLUT 预定义常数的复合布尔型 (位或). 你可以使用 mode 来指定颜色,
以及缓冲区的数量和类型.
这些常数是:
GLUT_RGBA or GLUT_RGB - 默认颜色模式
GLUT_INDEX - 颜色索引(?) 模式
显示模式允许你选择单或双缓冲区窗口.
相关常数是:
GLUT_SINGLE - 单缓冲区窗口
GLUT_DOUBLE - 双缓冲区,
平滑动画需要
这里还有更多关于缓冲区的常数:
GLUT_ACCUM - 聚集缓冲区
GLUT_STENCIL -
The stencil buffer (...翻译不出来)
GLUT_DEPTH - 深度缓冲区
现在,
假如你想要创建一个RGB窗口, 单缓冲以及一个深度缓冲区. 你需要把相关的常数去 OR 在一起来创建一个正确的常口
代码
...
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT
DEPTH);
...
经过以上步骤, 我们可以调用 glutCreateWindow 函数了
代码
int glutCreateWindow(char *title);
参数:
title -
窗口标题
glutCreateWindows 函数的返回值是索创建窗口的标示符. 你以后会用到这个标示符.
现在,
我们把上面的代码集合起来, 看看一次完整的窗口初始化:
代码
#include
void
main(int argc, char **argv) {
glutInit(&argc,
argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE |
GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(320,320);
glutCreateWindow("3D
Tech- GLUT Tutorial");
}
请注意包含文件, 我们需要 GLUT
的包含文件.
如果你运行了这段代码, 那么你将看到一个黑色的控制台窗口, 但是没有任何OpenGL窗口, 几秒钟以后, 这个窗口也消失了.
在我们开始渲染之前 我们还要做两件事情: 首先是告诉 GLUT 系统负责渲染的函数:
我们来创建一个渲染函数的例子. 这个函数将会清空颜色缓冲区,
并画出两个三角形:
代码
void renderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glVertex3f(-0.5,-0.5,0.0);
glVertex3f(0.5,0.0,0.0);
glVertex3f(0.0,0.5,0.0);
glEnd();
glFlush();
}
你可以给函数起任意的名字.
然而, 你必须告诉 GLUT 来使用这个函数进行渲染. 这叫做 注册回叫(callback) 函数. GLUT 将会在需要渲染的时候呼叫这个函数.
现在我们来告诉 GLUT 一旦我们的窗口被破坏(注意: 当窗口第一次被创建的时候, 这个函数也会被呼叫)
, 就调用renderScene函数.
GLUT 中有一个函数接受一个函数指针作为参数, 它将这个指针指向的函数作为渲染函数.
代码
void
glutDisplayFunc(void (*func)(void));
参数:
func - 渲染函数指针, NULL在这里非法
One last thing missing, that is telling GLUT that we're ready to
get in the application event processing loop. GLUT provides a function that gets
the application in a never ending loop, always waiting for the next event to
process. The GLUT function is glutMainLoop, and the syntax is as follows:
我们最后要做, 就是让程序进入事件处理循环. GLUT 给我们准备了一个函数来使程序进入一个无限循环(死循环),
永远在等待下一个需要处理的事件. 这个函数就是 glutMainLoop:
代码
void
glutMainLoop(void)
The code so far is presented bellow. Note that
we've added an include statement in order to start using standard OpenGL
functions, like glClear, glBegin, glVertex3f, and glEnd.
以下是完整的代码.
我们添加了一个新的包含文件, 以便于我们使用OpenGL的函数, 比如 glClear, glBegin, glVertex3f 和
glEnd.
如果你运行这你将会看到一个控制台窗口, 然后是一个画有白色三角形OpenGL窗口
代码
#include "gl/glut.h"
void renderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glVertex3f(-0.5,-0.5,0.0);
glVertex3f(0.5,0.0,0.0);
glVertex3f(0.0,0.5,0.0);
glEnd();
glFlush();
}
void
main(int argc, char **argv) {
glutInit(&argc,
argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE |
GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(320,320);
glutCreateWindow("3D
Tech- GLUT
Tutorial");
glutDisplayFunc(renderScene);
glutMainLoop();
}
使用vs2005,可以参考这里http://www.cecs.csulb.edu/~pnguyen/Using%20OpenGL%20in%20Visual%20Studio%202005.htm(全英文的,不过带图)