console下的glut模式OpenGL入门
使用glut进行OpenGL绘图,主要由以下几个部分组成:初始化和创建窗口,处理窗口和输入事件,加载颜色表,初始化和绘制三维物体,管理背景过程,运行程序。下面举例说明,阅读此例子的源代码,建议从main主函数开始,而不是从上至下。源程序
1, 新建一个win32控制台应用程序(注意,不是win32项目),在添加过程中,创建一个空的项目,然后,在解决方案资源管理器的源文件树目录下,添加一个cpp文件,文件可以命名为mian.cpp。
2, 添加绘图相关的头文件和库文件,在新建的main.cpp中,加入如下头文件:


#include < GL / gl.h >
#include < GL / glaux.h >
#include < GL / glu.h >
#include < gl / glut.h >
#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"glu32.lib")
#pragma comment(lib,"glaux.lib")
#pragma comment(lib,"GLUT32.LIB")
3, 添加程序进行鼠标交互操作时的相关变量
int mouseX, mouseY;
bool mouseButtonDown = false ; // 鼠标是否按下
float rotX = 16 , rotY = 0 ; // 初始化旋转角度,这里只用到了绕y轴旋转
4,添加程序空闲时的响应函数。在程序处于空闲状态时,反复重绘窗口,可以用于物体自动运动下的绘图刷新。
void Idle()
{
glutPostRedisplay(); // 标记当前窗口需要重新绘制
}
6,窗口大小改变时的响应函数。主要的设置包括视口大小的定义(glViewport)和投影的定义(gluPerspective)。


{
glViewport ( 0 , 0 ,iWidth,iHeight);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluPerspective( 65.0 ,(GLfloat)iWidth / (GLfloat)iHeight, 0.1 , 120.0 );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
7,添加绘图函数。这里绘制一个四面体,可以根据鼠标操作进行绕Y轴的旋转。


{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存
glLoadIdentity(); // 重置当前的模型观察矩阵
glTranslatef( 0.0f , 0.0f , - 6.0f ); // 左移1.5 单位,并移入屏幕6.0
glRotatef(rotY, 0.0f , 1.0f , 0.0f ); // 绕Y轴旋转金字塔
glBegin(GL_TRIANGLES); // 开始绘制金字塔的各个面
glColor3f( 1.0f , 0.0f , 0.0f ); // 红色
glVertex3f( 0.0f , 1.0f , 0.0f ); // 三角形的上顶点(前侧面)
glColor3f( 0.0f , 1.0f , 0.0f ); // 绿色
glVertex3f( - 1.0f , - 1.0f , 1.0f ); // 三角形的左下顶点(前侧面)
glColor3f( 0.0f , 0.0f , 1.0f ); // 蓝色
glVertex3f( 1.0f , - 1.0f , 1.0f ); // 三角形的右下顶点(前侧面)
glColor3f( 1.0f , 0.0f , 0.0f ); // 红色
glVertex3f( 0.0f , 1.0f , 0.0f ); // 三角形的上顶点(右侧面)
glColor3f( 0.0f , 0.0f , 1.0f ); // 蓝色
glVertex3f( 1.0f , - 1.0f , 1.0f ); // 三角形的左下顶点(右侧面)
glColor3f( 0.0f , 1.0f , 0.0f ); // 绿色
glVertex3f( 1.0f , - 1.0f , - 1.0f ); // 三角形的右下顶点(右侧面)
glColor3f( 1.0f , 0.0f , 0.0f ); // 红色
glVertex3f( 0.0f , 1.0f , 0.0f ); // 三角形的上顶点(后侧面)
glColor3f( 0.0f , 1.0f , 0.0f ); // 绿色
glVertex3f( 1.0f , - 1.0f , - 1.0f ); // 三角形的左下顶点(后侧面)
glColor3f( 0.0f , 0.0f , 1.0f ); // 蓝色
glVertex3f( - 1.0f , - 1.0f , - 1.0f ); // 三角形的右下顶点(后侧面)
glColor3f( 1.0f , 0.0f , 0.0f ); // 红色
glVertex3f( 0.0f , 1.0f , 0.0f ); // 三角形的上顶点(左侧面)
glColor3f( 0.0f , 0.0f , 1.0f ); // 蓝色
glVertex3f( - 1.0f , - 1.0f , - 1.0f ); // 三角形的左下顶点(左侧面)
glColor3f( 0.0f , 1.0f , 0.0f ); // 绿色
glVertex3f( - 1.0f , - 1.0f , 1.0f ); // 三角形的右下顶点(左侧面)
glEnd(); // 金字塔绘制结束
glutPostRedisplay();
glutSwapBuffers(); // 交换缓冲区
}
7,添加菜单定义函数,及菜单响应函数。这里的菜单是右键弹出式popup菜单,其中BuildPopupMenu建立菜单及菜单对应的ID号,菜单ID号的定义,置于main文件的上端。
SelectFromMenu为菜单消息响应函数。这里添加了两个菜单。如图所示。


MENU_TEST = 0 ,
MENU_EXIT
};
void SelectFromMenu( int idCommand)
{
switch (idCommand) {
case MENU_TEST:
// 写响应代码
MessageBox(NULL, " 测试 " , "" , 0 );
break ;
case MENU_EXIT:
exit( 0 );
break ;
}
glutPostRedisplay();
}
int BuildPopupMenu ( void )
{
int menu;
menu = glutCreateMenu(SelectFromMenu);
glutAddMenuEntry ( " 测试\tt " , MENU_TEST);
glutAddMenuEntry ( " Exit\tEsc " , MENU_EXIT);
return menu;
}
7,添加鼠标响应函数。鼠标响应函数主要包括鼠标按下响应和移动响应,mousebutton鼠标按下响应,MouseMotion是鼠标移动响应。


{
if (button == GLUT_LEFT_BUTTON) {
if (state == GLUT_DOWN) {
mouseX = x;
mouseY = y;
mouseButtonDown = true ;
} else {
mouseButtonDown = false ;
}
}
}
void MouseMotion( int x, int y)
{
int deltX, deltY;
// calculate mouse movement since click
deltY = x - mouseX;
deltX = y - mouseY;
// store new mouse position
mouseX = x;
mouseY = y;
if (mouseButtonDown) {
// rotate
rotX += deltX;
rotY += deltY;
glutPostRedisplay();
}
}
8,键盘响应函数。


{
switch (key) {
case ' t ' :
SelectFromMenu(MENU_TEST);
break ;
case 27 : // Esc
SelectFromMenu(MENU_EXIT);
break ;
}
}
9,主函数main.


{
GLsizei iWidth = 640.0 ; // 定义窗口大小
GLsizei iHeight = 480.0 ;
glutInit( & argc, argv); // glut初始化
// 指定函数glutCreateWindow()将创建的窗口模式,如是单缓存,还是双缓存,是RGB还是RGBA模式
// 另外还可以指定与窗口有一个相关联的深度缓存,模板缓存
glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE ); // 窗口显示模式,这里为RGB颜色模式,深度缓冲,双缓冲
glutInitWindowSize(iWidth, iHeight); // 窗口大小
glutInitWindowPosition( 100 , 100 ); // 窗口位置
glutCreateWindow( " 控制台下的OpenGL入门学习 " ); // 创建窗口
// 处理窗口和输入事件
BuildPopupMenu(); // 创建右键弹出式菜单
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutMouseFunc(MouseButton); // 鼠标按下,弹起的响应函数
glutMotionFunc(MouseMotion); // 鼠标移动时的响应函数
glutKeyboardFunc(Keyboard); // 键盘按下的响应函数
glutIdleFunc(Idle ); // 程序空闲时的处理函数为Idle()
// 初始化绘图环境,包括启用深度缓存,设置背景色,设置视口大小等
glClearColor( 0.0f , 0.0f , 0.0f , 0 ); // 设置背景色
glEnable(GL_DEPTH_TEST); // 启用深度测试
glDepthFunc(GL_LEQUAL); // 深度小或相等的时候也渲染
glutReshapeFunc(Resize ); // 窗口大小发生改变时的响应函数
glutDisplayFunc(DrawScene ); // 设置绘图函数为DrawScene()
glutMainLoop(); // 程序运行循环
return 0 ;
}
10,运行程序,如图所示。
附:
常见错误列表:
1新建的工程如果出现error C2664: “MessageBoxW”: 不能将参数2 从“const char [42]”转换为“LPCWSTR”这种错误, 将项目->配置属性->常规->字符集改为支持多字节字符集。
2 无法找到glut32.dll,程序无法启动。在默认情况下,glut是没有安装在vc的库里,只有gl等基本库及头文件,所以可以自己在网上下载最新的glut库,放到程序文件夹中,
3,无法定位程序输入点,_glutCreateWindowWithExit……,这种情况一般是你电脑里有多个glut32.dll可读路径,glut.dll版本冲突导致的。建议只使用一个最新版本glut库即可