实验二 OpenGL 的简单交互绘制
一、实验目的
1、理解 OpenGL 坐标系的概念,掌握 OpengGL 裁剪窗口、视区、显示窗口
的概念和它们之间的关系,学会计算世界坐标和屏幕坐标。
2、学会 OpenGL 的简单键盘交互操作。
3、进一步掌握 OpengGL 点、直线、多边形的绘制。
二、实验环境
硬件要求:
PC 机,主流配置,最好为独立显卡,显存 512M 以上。
软件环境:
操作系统:Windows XP。
语言开发工具:Microsoft Visual studio 2005/2008,Visual C++。
三、实验内容与要求
1、调出实验一的源代码运行,调整修改使得显示窗口在屏幕中央保持缺省
大小(300*300),绘制的矩形在显示窗口中央。如图 2-1 所示。
提示:
(1)添加修改窗口位置的函数 glutInitWindowPosition(int x, int y);
其中(x,y)为窗口左上角在屏幕上的位置。
(2)显示窗口的左下角坐标为(-1,-1),右上角坐标为(1,1)。
图 2-1
未修改前的初始源程序参考如下:
/*my first program.cpp*/
#include
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
//刷新颜色缓冲区
glRectf(0,0,0.5,0.5);
glFlush(); //用于刷新命令队列和缓冲区,使所有尚未被执行的
OpenGL 命令得到执行
}
void main(int argc, char** argv)
{
}
glutInit(&argc, argv);
//初始化 GLUT 库
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); //设置显示模式
glutCreateWindow("hello");
//创建窗口,标题为“hello”
glutDisplayFunc(display);
//用于绘制当前窗口
glutMainLoop();
//表示开始运行程序,用于程序的结尾
2、在实验一的基础上添加键盘交互,按 W 键绘制的矩形上移,按 S 键矩形
下移,按 A 键矩形左移,按 D 键矩形右移,如图 2-2。参考步骤如下:
(1)在主函数里添加键盘注册回调函数
glutKeyboardFunc(mykeyboard);
此函数可放在 glutDisplayFunc(display);后面。
(2)在 display()绘制函数中修改绘制矩形代码,用变量代替数值参数。
例如:glRectf(-0.5,-0.5,0.5,0.5)改为 glRectf(x1,y1,x2,y2);
(3)在程序中增加 mykeyboard 键盘子函数,并在如下代码中进行修改,
实现键盘控制矩形移动
void mykeyboard(unsigned char key, int x, int y)
{
switch(key)
{
case 'W':
case 'w':// 矩形对角坐标变量修改使得矩形上移
break;
case 'S':
case 's'://矩形对角坐标变量修改使得矩形下移
break;
case 'A':
case 'a'://矩形对角坐标变量修改使得矩形左移
break;
case 'D':
case 'd'://矩形对角坐标变量修改使得矩形右移
break;
}
//参数修改后调用重画函数,屏幕图形将发生改变
glutPostRedisplay();
}
图 2-2
3、设置窗口改变函数,使得矩形的长度和宽度等于 100,程序启动时矩形
仍在窗口中央,当显示窗口最大化时,绘制矩形也随之增大,如图 2-3。
(1)在 main 函数里添加注册窗口变化函数
glutReshapeFunc(myreshape); (放在 glutMainLoop()之前)
(2)在程序中添加窗口改变子函数,参数 w,h 为当前显示窗口的宽和高
void myreshape(GLsizei w, GLsizei h)
{
}
glViewport(0,0,w,h);
//设置视区位置
glMatrixMode(GL_PROJECTION);//设置投影变换模式
glLoadIdentity();
//调单位矩阵,清空当前矩阵堆栈
if(w<=h)
gluOrtho2D(0,300,0,300*(GLfloat)h/(GLfloat)w);
//设置裁剪窗口大小
else
gluOrtho2D(0,300*(GLfloat)w/(GLfloat)h,0,300);
a) 显示窗口改变前
b)显示窗口变大后
图 2-3
4、在矩形中间添加字符"Hello",观察结果;然后将"Hello"字符改为自己
名字的拼音或英文名字。如图 2-4 所示。
提示:在绘制矩形后添加如下代码:
glRasterPos2i((x1+x2)/2,(y1+y2)/2);
//定位当前光标
glutBitmapCharacter(GLUT_BITMAP_9_BY_15,'H');
//写字符"H"
glutBitmapCharacter(GLUT_BITMAP_9_BY_15,'e');
//写字符"e"
glutBitmapCharacter(GLUT_BITMAP_9_BY_15,'l');
//写字符"l"
glutBitmapCharacter(GLUT_BITMAP_9_BY_15,'l');
//写字符"l"
glutBitmapCharacter(GLUT_BITMAP_9_BY_15,'o');
//写字符"o"
图 2-4
5、按下列步骤操作,并分析裁剪窗口、视区和显示窗口的关系。
(1)修改视区大小为原来的一半。如图 2-5(a)。
(2)修改裁剪窗口的大小原来的一半;视区保持不变。如图 2-5(b)。
参考函数:
1、裁剪窗口设置函数:
gluOrtho2D(xwmin,xwmax,ywmin,ywmax);
xwmin,xwmax,ywmin,ywmax 为裁剪窗口在世界坐标系的位置,分别为
x 最小,x 最大,y 最小,y 最大
2、视区设置函数:
glViewport(startx,starty,viewport_width,viewport_height);
绘图区在显示窗口中的位置,以屏幕坐标系为参考
startx,starty,viewport_width,viewport_height 分别为绘图区在
显示窗口的起点位置, 以及绘图区的宽度和高度
图 2-5(a)
图 2-5(b)
6、自己参照讲义或教材按照自己的构思画二维平面图形,将上面的矩形替
换成自己构思的二维平面图形实现交互功能。注意顶点的顺序。修改以
上程序使得按数字 1 键 实现矩形用 WSAD 键控制上下左右移动,按 2 键
显示其他图形(三角形,点或多边形等)用 WSAD 键控制上下左右移动
参考函数:
1、点绘制举例
//点的大小设置
//顶点
glPointSize(2.0)
glBegin(GL_POINTS);
glColor3f(1.0,1.0,1.0);
glVertex2f(-0.5,-0.5);
glColor3f(1.0,0.0,1.0);
glVertex2f(-0.5,0.5);
glColor3f(0.0,1.0,1.0);
glVertex2f(0.5,0.5);
glColor3f(1.0,1.0,0.0);
glVertex2f(0.5,-0.5);
glEnd()
2、直线/三角形/四边形绘制举例
glLineWidth(2.0);
glBegin(GL_LINES);
// glBegin(GL_LINE_STRIP);
// glBegin(GL_LINE_LOOP);
// glBegin(GL_TRIANGLES);
// glBegin(GL_TRIANGLE_STRIP);
// glBegin(GL_TRIANGLE_FAN);
// glBegin(GL_QUADS);
// glBegin(GL_TRIANGLE_STRIP);
glVertex2f(-0.5,0.5);
glVertex2f(-0.5,-0.5);
glColor3f(1.0,1.0,1.0);
glVertex2f(-0.5,0.5);
glColor3f(1.0,1.0,0.0);
glVertex2f(0.5,-0.5);
glEnd();
3、多边形举例
glBegin(GL_POLYGON);
glVertex2f(-0.5,0.5);
glVertex2f(-0.5,-0.5);
glColor3f(1.0,1.0,1.0);
glVertex2f(0,-0.5);
glColor3f(1.0,1.0,0.0);
glVertex2f(0.5,-0.5);
glVertex2f(0.5,0.5);
glEnd();
思 考 题 : 实 验 中 当 矩 形 由 坐 标 (-0.5,-0.5,0.5,0.5) 变 到
(100,100,200,200), 矩形仍然显示在显示窗口的中间位置,思考裁剪窗口
设 置 函 数 gluOrtho2D(xwmin,xwmax,ywmin,ywmax); 和 视 区 设 置 函 数
glViewport(startx,starty,viewport_width,viewport_height) 的 设 置 应
如何进行修改,有何规律?