实验三 OpenGL的简单交互绘制

ZZU的学弟学妹们不要抄作业哦~(`Д´)

一、实验目的

1.理解OpenGL坐标系的概念,掌握OpengGL裁剪窗口、视区、显示窗口的概念和它们之间的关系,学会计算世界坐标和屏幕坐标。

2.学会OpenGL的简单键盘交互操作。

3.学会OpenGL的简单字符绘制。

4.进一步掌握OpengGL点、直线、多边形的绘制。

、实验内容

1.调出实验一的源代码运行,调整修改使得显示窗口在屏幕中央保持缺省大小(300*300),绘制的矩形在显示窗口中央。如图3-1所示。

提示:

1)添加修改窗口位置的函数glutInitWindowPosition(int x, int y);其中(x,y)为窗口左上角在屏幕上的位置。

2)显示窗口的左下角坐标为(-1,-1),右上角坐标为(1,1)。

实验三 OpenGL的简单交互绘制_第1张图片

                                     图3-1 中央矩形

 

2.在实验一的基础上添加键盘交互,按W键绘制的矩形上移,按S键矩形下移,按A键矩形左移,按D键矩形右移,如图3-2。参考步骤如下:

1)在主函数里添加注册键盘回调函数

glutKeyboardFunc(mykeyboard);

此函数可放在 glutDisplayFunc(display);后面。

2)在display()绘制函数中修改绘制矩形代码,用变量代替数值参数。

例如:

glRectf(-0.5,-0.5,0.5,0.5)

改为

glRectf(x1,y1,x2,y2);

程序前面加上变量声明和初始值,如:

float x1=-0.5,y1=-0.5,x2=0.5,y2=0.5;  

注意语句的位置。

  1. 在程序中增加mykeyboard键盘子函数,可放在display()函数之后。并在如下代码中进行修改,实现键盘控制矩形移动,运行程序自行测试。

void mykeyboard(unsigned char key, int x, int y)

{

switch(key)

{   

case 'W':

       case 'w':// 矩形对角坐标变量修改使得矩形上移

y1+=0.1; y2+=0.1;

              break;

case 'S':

      case 's'://矩形对角坐标变量修改使得矩形下移

                  y1-=0.1;y2-=0.1;

           break;

case 'A':

       case 'a'://矩形对角坐标变量修改使得矩形左移

                  x1-=0.1; x2-=0.1;

           break;

case 'D':

       case 'd'://矩形对角坐标变量修改使得矩形右移

                  x1+=0.1; x2+=0.1;

           break;   

       }

    //参数修改后调用重画函数,屏幕图形将发生改变

       glutPostRedisplay();  

}

实验三 OpenGL的简单交互绘制_第2张图片实验三 OpenGL的简单交互绘制_第3张图片实验三 OpenGL的简单交互绘制_第4张图片实验三 OpenGL的简单交互绘制_第5张图片

                                             图3-2 矩形的上下左右移动

 

3.设置窗口改变函数,使得矩形的长度和宽度等于100,程序启动时矩形仍在窗口中央,当显示窗口最大化时,绘制矩形也随之增大,如图3-3所示。         

1)在main函数里添加注册窗口变化函数

glutReshapeFunc(myreshape); //放在glutMainLoop()之前

2)在程序中添加窗口改变子函数,参数w,h为当前显示窗口的宽和高

void myreshape(GLsizei w, GLsizei h)

{

glViewport(0,0,w,h);   //设置视区位置

glMatrixMode(GL_PROJECTION);//设置投影变换模式

glLoadIdentity();  //调单位矩阵,清空当前矩阵堆栈

gluOrtho2D(0,300,0,300);  

}

3) 此时,矩形的初始变量经重新计算后为:

float x1=100,x1=100,x2=200,y2=200;

 

注意:请同学们自己思考为什么矩形初始的初始变量由原来的(-0.5,-0.5,0.5,0.5)变为(100,100,200,200) ?裁剪窗口设置函数gluOrtho2D(xwmin,xwmax,ywmin,ywmax); 和视区设置函数 glViewport(startx,starty,viewport_width,viewport_height)的设置有何规律?

答:myreshape函数改变了窗口的原点坐标和坐标单位值。

 

此时,按下键盘“WADS”键进行交互移动,矩形的移动距离较之前有什么变化?要保持以前的移动频率,程序应该如何修改?

答:移动的距离变得很小,要保持以前的移动频率应该修改mykeyboard函数的坐标改变值。

实验三 OpenGL的简单交互绘制_第6张图片          实验三 OpenGL的简单交互绘制_第7张图片

       a) 显示窗口改变前                                          b)显示窗口变大后

3-3 显示窗口改变

4.在矩形中间添加字符"Hello",观察结果;然后将"Hello"字符改为自己名字的拼音或英文名字。如图3-4所示。

提示:在绘制矩形后添加如下代码:

glColor3f(1,0,0);

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"

 

注意:运行程序,效果如图3-4所示。但是如果此时,按下键盘“WADS”键进行交互移动,程序会发生什么变化?要保持矩形白色,字符红色,程序应该如何修改?

答:字符会跟着动,不用改啊。。。

如果字符颜色设置语句glColor3f(1,0,0);放在定位光标语句glRasterPos2i((x1+x2)/2,(y1+y2)/2); 之后,运行又会发生什么变化?自己总结设置字符颜色语句的顺序规律。

答:字符颜色会变成矩形的颜色。

实验三 OpenGL的简单交互绘制_第8张图片

3-4 添加字符

 

5.自己参照讲义或教材按照自己的构思画二维平面图形,将上面的矩形替换成自己构思的二维平面图形实现交互功能,注意顶点的顺序。并在画面上标注自己的姓名。

实验三 OpenGL的简单交互绘制_第9张图片实验三 OpenGL的简单交互绘制_第10张图片

 

实验三 OpenGL的简单交互绘制_第11张图片 实验三 OpenGL的简单交互绘制_第12张图片

 

 

功能描述:按W、S、A、D会上下左右移动,按Q缩小,按E放大。

 

三、思考题

按下列步骤操作,并分析裁剪窗口、视区和显示窗口的关系。

1)修改视区大小为原来的一半。如图3-5a所示

2)修改裁剪窗口的大小原来的一半;视区保持不变。如图3-5b所示

实验三 OpenGL的简单交互绘制_第13张图片实验三 OpenGL的简单交互绘制_第14张图片

                   a)修改视区                                        b)修改窗口                 

                                                      图3-5

参考函数:

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分别为绘图区在显示窗口的起点位置, 以及绘图区的宽度和高度

  1. 修改以上程序是的按数字1建实现矩形用W、S、A、D键控制上、下、左、右移动,按2键显示自己构思的其他2D图形(三角形、点或多边形等),用W、S、A、D键控制上、下、左、右移动。

 

四、代码

#include
#include
#include

float x1=100, y1=0, x2=0, y2=100,x3=0, y3=0;
int flag = 0;
void display(void)
{
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);//设置清屏颜色
	glClear(GL_COLOR_BUFFER_BIT);//刷新颜色缓存区

	if(flag==1) glRectf(x1, y1, x2, y2); 

	if(flag==2)
	{
		glColor3f(0.5, 0.5, 0.5);
		glBegin(GL_TRIANGLES);
		glVertex2f(x1, y1);
		glVertex2f(x2, y2);
		glVertex2f(x3, y3);
		glEnd();
	}


	glFlush();//刷新命令队列和缓存区,是所有尚未执行的OpenGL命令得到执行
}


void mykeyboard(unsigned char key, int x, int y)
{
	switch (key)
	{
	case '1':
		flag = 1;
		break;
	case '2':
		flag = 2;
		break;
	case 'W':
	case 'w':// 矩形对角坐标变量修改使得矩形上移
		y1 += 10; y2 += 10; y3+=10;
		break;
	case 'S':
	case 's'://矩形对角坐标变量修改使得矩形下移
		y1 -= 10;y2 -= 10; y3 -= 10;
		break;
	case 'A':
	case 'a'://矩形对角坐标变量修改使得矩形左移
		x1 -= 10; x2 -= 10; x3-=10;
		break;
	case 'D':
	case 'd'://矩形对角坐标变量修改使得矩形右移
		x1 += 10; x2 += 10; x3 += 10;
		break;
	case 'Q':
	case 'q'://缩小
		x1 -=10;
		y2 -=10;
		break;
	case 'E'://放大
	case 'e':
		x1 += 10;
		y2 += 10;
		break;
	}
	
	//参数修改后调用重画函数,屏幕图形将发生改变
	glutPostRedisplay();
}

void myreshape(GLsizei w, GLsizei h)
{
	glViewport(0, 0, w, h);   //设置视区位置
	glMatrixMode(GL_PROJECTION);//设置投影变换模式
	glLoadIdentity();  //调单位矩阵,清空当前矩阵堆栈
	gluOrtho2D(0, 300, 0, 300);
}

int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR 						lpCmdLine, int nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);
	char *argv[] = { "hello "," " };
	int argc = 2;
	glutInit(&argc, argv);    //初始化GLUT库;
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);   //设置显示模式;(缓冲,颜色类型)
	glutInitWindowSize(300, 300);//绘制窗口大小
	glutInitWindowPosition(1024 / 2 - 250, 768 / 2 - 250);//窗口左上角在屏幕的位置
	glutCreateWindow("hello");  //创建窗口,标题为“hello”;
	glutDisplayFunc(display);  //显示回调函数用于绘制当前窗口;
	glutKeyboardFunc(mykeyboard);
	glutReshapeFunc(myreshape);
	glutMainLoop();   //表示开始运行程序,用于程序的结尾;
	return 0;
}

 

你可能感兴趣的:(OpenGL)