实验三 OpenGL的简单交互绘制newWord下载.docx
- 文档编号:20468855
- 上传时间:2023-01-23
- 格式:DOCX
- 页数:16
- 大小:74.91KB
实验三 OpenGL的简单交互绘制newWord下载.docx
《实验三 OpenGL的简单交互绘制newWord下载.docx》由会员分享,可在线阅读,更多相关《实验三 OpenGL的简单交互绘制newWord下载.docx(16页珍藏版)》请在冰豆网上搜索。
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
char*argv[]={"
hello"
"
"
};
intargc=2;
//must/shouldmatchthenumberofstringsinargv
glutInit(&
argc,argv);
//初始化GLUT库;
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
//设置显示模式;
(缓冲,颜色类型)
glutInitWindowSize(500,500);
glutInitWindowPosition(1024/2-250,768/2-250);
glutCreateWindow("
Hello"
);
//创建窗口,标题为“hello”;
glutDisplayFunc(display);
//用于绘制当前窗口;
glutMainLoop();
//表示开始运行程序,用于程序的结尾;
return0;
}
voiddisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
//刷新颜色缓冲区
glRectf(-0.5,-0.5,0.5,0.5);
glFlush();
//用于刷新命令队列和缓冲区,使所有尚未被执行的OpenGL命令得到执行
2、在实验一的基础上添加键盘交互,按W键绘制的矩形上移,按S键矩形下移,按A键矩形左移,按D键矩形右移,如图2-2。
参考步骤如下:
(1)在主函数里添加注册键盘回调函数
glutKeyboardFunc(mykeyboard);
此函数可放在glutDisplayFunc(display);
后面。
并在程序头部声明添加键盘回调函数:
voidmykeyboard(unsignedcharkey,intx,inty);
(2)在display()绘制函数中修改绘制矩形代码,用变量代替数值参数。
例如:
glRectf(-0.5,-0.5,0.5,0.5)改为glRectf(x1,y1,x2,y2);
程序前面加上变量声明和初始值,如:
floatx1=-0.5,y1=-0.5,x2=0.5,y2=0.5;
注意语句的位置。
(3)在程序中增加mykeyboard键盘子函数,可放在display()函数之后。
并在如下代码中进行修改,实现键盘控制矩形移动,运行程序自行测试。
voidmykeyboard(unsignedcharkey,intx,inty)
switch(key)
{case'
W'
:
case'
w'
//矩形对角坐标变量修改使得矩形上移
y1+=0.1;
y2+=0.1;
break;
case'
S'
case'
s'
//矩形对角坐标变量修改使得矩形下移
y1-=0.1;
y2-=0.1;
A'
case'
a'
//矩形对角坐标变量修改使得矩形左移
x1-=0.1;
x2-=0.1;
D'
d'
//矩形对角坐标变量修改使得矩形右移
x1+=0.1;
x2+=0.1;
}
//参数修改后调用重画函数,屏幕图形将发生改变
glutPostRedisplay();
}
图2-2
3、设置窗口改变函数,使得矩形的长度和宽度等于100,程序启动时矩形仍在窗口中央,当显示窗口最大化时,绘制矩形也随之增大,如图2-3。
(1)在main函数里添加注册窗口变化函数
glutReshapeFunc(myreshape);
(放在glutMainLoop()之前)
并在程序头部声明添加窗口变换函数:
voidmyreshape(GLsizeiw,GLsizeih);
(2)在程序中添加窗口改变子函数,参数w,h为当前显示窗口的宽和高
voidmyreshape(GLsizeiw,GLsizeih)
glViewport(0,0,w,h);
//设置视区位置
glMatrixMode(GL_PROJECTION);
//设置投影变换模式
glLoadIdentity();
//调单位矩阵,清空当前矩阵堆栈
gluOrtho2D(0,300,0,300);
3)此时,矩形的初始变量经重新计算后为:
floatx1=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)的设置有何规律?
此时,按下键盘“WADS”键进行交互移动,矩形的移动距离较之前有什么变化?
要保持以前的移动频率,程序应该如何修改?
a)显示窗口改变前b)显示窗口变大后
图2-3
4、在矩形中间添加字符"
,观察结果;
然后将"
字符改为自己名字的拼音或英文名字。
如图2-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"
l'
l"
o'
o"
注意:
运行程序,效果如图2-4所示。
但是如果此时,按下键盘“WADS”键进行交互移动,程序会发生什么变化?
要保持矩形白色,字符红色,程序应该如何修改?
如果字符颜色设置语句glColor3f(1,0,0);
放在定位光标语句glRasterPos2i((x1+x2)/2,(y1+y2)/2);
之后,运行又会发生什么变化?
请同学自己总结设置字符颜色语句的顺序规律。
图2-4
5、自己参照讲义或教材按照自己的构思画二维平面图形,将上面的矩形替换成自己构思的二维平面图形实现交互功能,注意顶点的顺序。
并在画面上标注自己的姓名。
3.2鼠标交互
(1)鼠标画线
阅读OpenGL鼠标画线程序,能够实现在绘制窗口用鼠标交互绘制若干条直线,鼠标左键首先按下,确定直线的起始点,鼠标左键按下同时移动,看到画线过程,鼠标左键松开时,确定直线的终点,可重复画多条直线。
实现主要思路:
1)写出画静止若干条直线程序框架,坐标用变量替代;
2)在主函数里注册鼠标按钮响应函数和鼠标移动响应函数;
3)在鼠标按钮响应子函数里,给出鼠标按钮响应事件;
4)在鼠标移动响应子函数里,给出鼠标移动响应事件;
5)读懂程序并分析程序,保留程序。
//鼠标画线小程序
#defineN1000//maximumlinenumbers
intww,hh;
//fordisplaywindowwidthandheight
intline[N][4],k=0;
//forline'
sendpointcoordinatesandlinenumber
voidMyinit(void);
voidReshape(intw,inth);
voidmyMouse(intbutton,intstate,intx,inty);
voidmyMotion(intx,inty);
voidDisplay(void);
voiddrawlines();
intAPIENTRY_tWinMain(HINSTANCEhInstance,
glutInitWindowSize(800,600);
//设置显示窗口大小
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
(注意双缓冲)
鼠标画线小程序演示"
//创建显示窗口
Myinit();
glutDisplayFunc(Display);
//注册显示回调函数
glutMouseFunc(myMouse);
//注册鼠标按钮回调函数
glutMotionFunc(myMotion);
//注册鼠标移动回调函数
glutReshapeFunc(Reshape);
//注册窗口改变回调函数
//进入事件处理循环
voidMyinit(void)
glClearColor(0.0,0.0,0.0,0.0);
glLineWidth(3.0);
//渲染绘制子程序--------------------------------------------------------------------------
voidDisplay(void)
//刷新颜色缓冲区;
drawlines();
//画线子程序;
glutSwapBuffers();
//双缓冲的刷新模式;
//-----------------------------------------------
voidReshape(intw,inth)//窗口改变时自动获取显示窗口的宽w和高h
//投影矩阵模式
//矩阵堆栈清空
glViewport(0,0,w,h);
//设置视区大小
gluOrtho2D(0,w,0,h);
//设置裁剪窗口大小
ww=w;
hh=h;
//鼠标按钮响应事件..
voidmyMouse(intbutton,intstate,intx,inty)
if(button==GLUT_LEFT_BUTTON&
&
state==GLUT_DOWN)
line[k][0]=x;
//线段起点x坐标
line[k][1]=hh-y;
//线段终点y坐标
state==GLUT_UP)
line[k][2]=x;
line[k][3]=hh-y;
k++;
//鼠标移动时获得鼠标移动中的坐标-----------------------------------------------------
voidmyMotion(intx,inty)
//gettheline'
smotionpoint
line[k][2]=x;
//动态终点的x坐标
line[k][3]=hh-y;
//动态终点的y坐标
glutPostRedisplay();
//画线子程序
voiddrawlines()
for(inti=0;
i<
=k;
i++)//********
{
glBegin(GL_LINES);
glVertex2f(line[i][0],line[i][1]);
glVertex2f(line[i][2],line[i][3]);
glEnd();
}
鼠标画线程序运行后,程序效果如图3-3所示。
图3-3
(2)鼠标绘制矩形(将此修改代码贴到实验报告中)
修改鼠标画线程序,要求:
能够实现在绘制窗口用鼠标交互绘制若干矩形,鼠标左键首先按下,确定矩形对角线的起始点,鼠标左键按下同时移动时,看到画矩形过程,鼠标左键松开,确定矩形对角线的另一点,可重复画多个矩形。
如图3-4所示。
图3-4
四、思考题:
按下列步骤操作,并分析裁剪窗口、视区和显示窗口的关系。
(1)修改视区大小为原来的一半。
如图2-5(a)。
(2)修改裁剪窗口的大小原来的一半;
视区保持不变。
如图2-5(b)。
图2-5(a)图2-5(b)
(3)修改以上程序使得按数字1键实现矩形用WSAD键控制上下左右移动,按2键显示自己构思的其他2D图形(三角形,点或多边形等)用WSAD键控制上下左右移动
五、参考函数:
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分别为绘图区在显示窗口的起点位置,以及绘图区的宽度和高度
3、键盘响应相关函数:
3.1glutKeyboardFunc(void*f(unsignedcharkey,intx,inty))
注册键盘响应函数,按下键盘中某键,程序将’key’值作为字符返回给函数f,用户可决定下一步的行动。
该函数调用放在主程序main()中
⏹例如,当用户按下’q’或’Q’或Esc键(ASCII27)时,程序退出。
⏹glutKeyboardFunc(mykey);
//主函数注册键盘响应函数
⏹voidmykey((unsignedcharkey,intx,inty)//键盘响应函数
⏹{if(key==‘q’||key==‘Q’||key==‘\27’)
⏹exit(0);
⏹}
3.2特殊键响应
voidglutSpecialFunc(void(*f)(intkey,intx,inty))
当用户按下一个特殊键时,调用函数f响应用户需求。
使用方法同glutKeyboardFunc(void*f(unsignedcharkey,intx,inty))
例,if(key==GLUT_KEY_F1)….
if(key==GLUT_KEY_UP)….
非ASCII键
回调参数值
Fi(i=1,2,…,12)
GLUT_KEY_Fi
PageUp
GLUT_KEY_PAGE_UP
PageDown
GLUT_KEY_PAGE_DOWN
左方向键
GLUT_KEY_LEFT
右方向键
GLUT_KEY_RIGHT
上方向键
GLUT_KEY_UP
下方向键
GLUT_KEY_DOWN
Home
GLUT_KEY_HOME
End
GLUT_KEY_END
3.3组合键intglutGetModifers()
在键盘响应事件中当键盘按下时返回GLUT_ACTIVE_SHIFT,GLUT_ACTIVE_CTRL,或GLUT_ACTIVE_ALT值
例,if((glutGetModifers()==GLUT_ACTIVE_CTRL)&
((key==‘c’)||(key==‘C’)))exit(0);
4、鼠标按钮响应相关函数
⏹voidglutMouseFunc(void(*f)(intbutton,intstate,intx,inty))
☐Mousecallbackfunction。
在主程序中调用。
☐button:
⏹GLUT_LEFT_BUTTON,GLUT_MIDDLE_BUTTON,GLUT_RIGHT_BUTTON
☐state:
⏹GLUT_UP,GLUT_DOWN
☐x,y:
返回鼠标在窗口的位置(原点在左上角)。
例如,
主程序注册:
glutMouseFunc(mymouse);
voidmymouse(intx,inty,intbutton,intstate)
if(state==GLUT_DOWN&
button==GLUT_LEFT_BUTTON)
exit();
//按下左键退出
5、注册鼠标移动响应函数
voidglutMotionFunc(void(*f)(intx,inty))
该函数在主程序中调用。
(x,y)鼠标的位置,原点在左上角
⏹moveevent:
鼠标按钮按下时的鼠标移动
☐glutMotionFunc(mymousemotion);
mymousemotion(intx,inty)
·
//鼠标移动时触发的事件代码
⏹passivemoveevent:
鼠标按钮松开时的鼠标移动
☐glutPassveMotionFunc(mymousepmotion);
⏹entryevent:
鼠标进入或离开窗口时的事件
☐glutEntryFunc(mymouseentry);
⏹voidglutEntryFunc(void(*f)(intstate))
⏹x,y-鼠标的位置,原点在左上角
⏹state:
GLUT_ENTEREDorGLUT_LEFT
例,鼠标绘制折线代码
⏹鼠标按下时开始画折线,鼠标按钮松开时结束。
glutMotionFunc(mymotion);
voidmymotion(intx,inty)
{。
。
if(first_time_called)
glBegin(GL_LINE_STRIP);
glVertex2f(sx*(GLfloat)x,sy*(GLfloat)(h-y));
。
⏹注意:
鼠标按钮松开时产生glEnd()
六、实验演示录像
1.win32_lab3_interactive.exe
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验三 OpenGL的简单交互绘制new 实验 OpenGL 简单 交互 绘制 new
![提示](https://static.bdocx.com/images/bang_tan.gif)