计算机图形学OpenGL版实验14Word文件下载.docx
- 文档编号:17031761
- 上传时间:2022-11-28
- 格式:DOCX
- 页数:17
- 大小:140.96KB
计算机图形学OpenGL版实验14Word文件下载.docx
《计算机图形学OpenGL版实验14Word文件下载.docx》由会员分享,可在线阅读,更多相关《计算机图形学OpenGL版实验14Word文件下载.docx(17页珍藏版)》请在冰豆网上搜索。
)
在glutDisplayFunc函数中,我们设置了“当需要画图时,请调用myDisplay函数”。
于是myDisplay函数就用来画图。
观察myDisplay中的三个函数调用,发现它们都以gl开头。
这种以gl开头的函数都是OpenGL的标准函数,下面对用到的函数进行介绍:
1)glClearColor(0.0,0.0,0.0,0.0):
将清空颜色设为黑色(为什么会有四个参数?
);
2)glClear(GL_COLOR_BUFFER_BIT):
将窗口的背景设置为当前清空颜色;
3)glRectf,画一个矩形。
四个参数分别表示了位于对角线上的两个点的横、纵坐标;
4)glFlush,保证前面的OpenGL命令立即执行(而不是让它们在缓冲区中等待)。
四、实验代码:
#include<
voidmydisplay(void)
{
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f,1.0f,1.0f);
glRectf(-0.5f,-0.5f,0.5f,0.5f);
glBegin(GL_TRIANGLES);
glColor3f(1.0f,0.0f,0.0f);
glVertex2f(0.0f,1.0f);
glColor3f(0.0f,1.0f,0.0f);
glVertex2f(0.8f,-0.5f);
glColor3f(0.0f,0.0f,1.0f);
glVertex2f(-0.8f,-0.5f);
glEnd();
glBegin(GL_LINES);
glVertex2i(-0.6f,-0.6f);
glVertex2i(0.6f,-0.6f);
glVertex2i(0.0f,0.0f);
glPointSize(3);
glBegin(GL_POINTS);
glVertex2f(-0.4f,-0.4f);
glVertex2f(0.0f,-0.0f);
glVertex2f(0.4f,0.4f);
glFlush();
}
intmain(intargc,char*argv[])
glutInit(&
argc,argv);
glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);
glutInitWindowPosition(100,100);
glutInitWindowSize(400,400);
glutCreateWindow("
HelloWorld!
"
);
glutDisplayFunc(&
mydisplay);
glutMainLoop();
return0;
五、结果截图:
实验2直线生成算法实现
理解基本图形元素光栅化的基本原理,掌握一种基本图形元素光栅化算法,利用OpenGL实现直线光栅化的DDA算法。
(1)根据所给的直线光栅化的示范源程序,在计算机上编译运行,输出正确结果;
(2)指出示范程序采用的算法,以此为基础将其改造为中点线算法或Bresenham算法,写入实验报告;
(3)根据示范代码,将其改造为圆的光栅化算法,写入实验报告;
(4)了解和使用OpenGL的生成直线的命令,来验证程序运行结果。
三、实验原理:
(1)数学上的直线没有宽度,但OpenGL的直线则是有宽度的。
同时,OpenGL的直线必须是有限长度,而不是像数学概念那样是无限的。
可以认为,OpenGL的“直线”概念与数学上的“线段”接近,它可以由两个端点来确定。
这里的线由一系列顶点顺次连结而成,有闭合和不闭合两种。
(2)首次打开窗口、移动窗口和改变窗口大小时,窗口系统都将发送一个事件,以通知程序员。
如果使用的是GLUT,通知将自动完成,并调用向glutReshapeFunc()注册的函数。
该函数必须完成下列工作:
(1)重新建立用作新渲染画布的矩形区域;
(2)定义绘制物体时使用的坐标系。
#include<
voidLineDDA(intx0,inty0,intx1,inty1/*,intcolor*/)
intx,dy,dx,y;
floatm;
dx=x1-x0;
dy=y1-y0;
m=dy/dx;
y=y0;
glColor3f(1.0f,1.0f,0.0f);
glPointSize
(1);
for(x=x0;
x<
=x1;
x++)
glBegin(GL_POINTS);
glVertex2i(x,(int)(y+0.5));
glEnd();
y+=m;
voidmyDisplay(void)
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f,0.0f,0.0f);
glRectf(25.0,25.0,75.0,75.0);
glPointSize(5);
glColor3f(0.0f,1.0f,0.0f);
glVertex2f(0.0f,0.0f);
LineDDA(0,0,200,300);
glBegin(GL_LINES);
glVertex2f(100.0f,0.0f);
glVertex2f(180.0f,240.0f);
glFlush();
voidInit()
glClearColor(0.0,0.0,0.0,0.0);
glShadeModel(GL_FLAT);
voidReshape(intw,inth)
glViewport(0,0,(GLsizei)w,(GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,(GLdouble)w,0.0,(GLdouble)h);
intmain(intargc,char*argv[])
glutInit(&
glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);
glutInitWindowPosition(100,100);
glutInitWindowSize(400,400);
glutCreateWindow("
Init();
glutDisplayFunc(myDisplay);
glutReshapeFunc(Reshape);
glutMainLoop();
return0;
实验3OpenGL几何变换
理解掌握一个OpenGL程序平移、旋转、缩放变换的方法。
(1)阅读实验原理,运行示范实验代码,掌握OpenGL程序平移、旋转、缩放变换的方法;
(2)根据示范代码,尝试完成实验作业;
(1)OpenGL下的几何变换
在OpenGL的核心库中,每一种几何变换都有一个独立的函数,所有变换都在三维空间中定义。
平移矩阵构造函数为glTranslate<
f,d>
(tx,ty,tz),作用是把当前矩阵和一个表示移动物体的矩阵相乘。
tx,ty,tz指定这个移动物体的矩阵,它们可以是任意的实数值,后缀为f(单精度浮点float)或d(双精度浮点double),对于二维应用来说,tz=0.0。
旋转矩阵构造函数为glRotate<
(theta,vx,vy,vz),作用是把当前矩阵和一个表示旋转物体的矩阵相乘。
theta,vx,vy,vz指定这个旋转物体的矩阵,物体将绕着(0,0,0)到(x,y,z)的直线以逆时针旋转,参数theta表示旋转的角度。
向量v=(vx,vy,vz)的分量可以是任意的实数值,该向量用于定义通过坐标原点的旋转轴的方向,后缀为f(单精度浮点float)或d(双精度浮点double),对于二维旋转来说,vx=0.0,vy=0.0,vz=1.0。
缩放矩阵构造函数为glScale<
(sx,sy,sz),作用是把当前矩阵和一个表示缩放物体的矩阵相乘。
sx,sy,sz指定这个缩放物体的矩阵,分别表示在x,y,z方向上的缩放比例,它们可以是任意的实数值,当缩放参数为负值时,该函数为反射矩阵,缩放相对于原点进行,后缀为f(单精度浮点float)或d(双精度浮点double)。
(2)OpenGL下的各种变换简介
我们生活在一个三维的世界——如果要观察一个物体,我们可以:
1、从不同的位置去观察它(人运动,选定某个位置去看)。
(视图变换)
2、移动或者旋转它,当然了,如果它只是计算机里面的物体,我们还可以放大或缩小它(物体运动,让人看它的不同部分)。
(模型变换)
3、如果把物体画下来,我们可以选择:
是否需要一种“近大远小”的透视效果。
另外,我们可能只希望看到物体的一部分,而不是全部(指定看的范围)。
(投影变换)
4、我们可能希望把整个看到的图形画下来,但它只占据纸张的一部分,而不是全部(指定在显示器窗口的那个位置显示)。
(视口变换)
这些,都可以在OpenGL中实现。
从“相对移动”的观点来看,改变观察点的位置与方向和改变物体本身的位置与方向具有等效性。
在OpenGL中,实现这两种功能甚至使用的是同样的函数。
由于模型和视图的变换都通过矩阵运算来实现,在进行变换前,应先设置当前操作的矩阵为“模型视图矩阵”。
设置的方法是以GL_MODELVIEW为参数调用glMatrixMode函数,像这样:
glMatrixMode(GL_MODELVIEW);
该语句指定一个4×
4的建模矩阵作为当前矩阵。
voidinit(void)
glClearColor(1.0,1.0,1.0,0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(-5.0,5.0,-5.0,5.0);
//设置显示的范围是X:
-5.0~5.0,Y:
-5.0~5.0
glMatrixMode(GL_MODELVIEW);
voiddrawSquare(void)//绘制中心在原点,边长为2的正方形
glBegin(GL_POLYGON);
//顶点指定需要按逆时针方向
glVertex2f(-1.0f,-1.0f);
//左下点
glVertex2f(1.0f,-1.0f);
//右下点
glVertex2f(1.0f,1.0f);
//右上点
glVertex2f(-1.0f,1.0f);
//左上点
glEnd();
voidmyDraw(void)
glClear(GL_COLOR_BUFFER_BIT);
//清空
//将当前矩阵设为单位矩阵
glPushMatrix();
glTranslatef(0.0f,2.0f,0.0f);
glScalef(3.0,0.5,1.0);
glColor3f(1.0,0.0,0.0);
drawSquare();
//上面红色矩形
glPopMatrix();
glTranslatef(-3.0,0.0,0.0);
glRotatef(45.0,0.0,0.0,1.0);
glColor3f(0.0,1.0,0.0);
//中间左菱形
glTranslatef(3.0,0.0,0.0);
glColor3f(0.0,0.7,0.0);
//中间中菱形
glColor3f(0.0,0.4,0.0);
//中间右菱形
glTranslatef(0.0,-3.0,0.0);
glScalef(4.0,1.5,1.0);
glColor3f(0.0,0.0,1.0);
//下面蓝色矩形
glFlush();
voidmain(intargc,char**argv)
glutInit(&
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowPosition(0,0);
glutInitWindowSize(600,600);
glutCreateWindow("
几何变换函数综合示例"
init();
glutDisplayFunc(myDraw);
glutMainLoop();
五、结果实例:
实验4编码裁剪算法
了解二维图形裁剪的原理(点的裁剪、直线的裁剪、多边形的裁剪),利用VC+OpenGL实现直线的裁剪算法。
(1)理解直线裁剪的原理(Cohen-Surtherland算法、梁友栋算法)
(2)利用VC+OpenGL实现直线的编码裁剪算法,在屏幕上用一个封闭矩形裁剪任意一条直线。
(3)调试、编译、修改程序。
(4)尝试实现梁友栋裁剪算法。
编码裁剪算法中,为了快速判断一条直线段与矩形窗口的位置关系,采用了如图所示的空间划分和编码方案。
裁剪一条线段时,先求出两端点所在的区号code1和code2,若code1=0且code2=0,则说明线段的两个端点均在窗口内,那么整条线段必在窗口内,应取之;
若code1和code2经按位与运算的结果不为0,则说明两个端点同在窗口的上方、下方、左方或右方。
这种情况下,对线段的处理是弃之。
如果上述两种条件都不成立,则按第三种情况处理。
求出线段与窗口某边的交点,在交点处把线段一分为二,其中必有一段完全在窗口外,可弃之,对另一段则重复上述处理。
stdio.h>
stdlib.h>
#defineLEFT_EDGE1
#defineRIGHT_EDGE2
#defineBOTTOM_EDGE4
#defineTOP_EDGE8
voidLineGL(intx0,inty0,intx1,inty1)
glVertex2f(x0,y0);
glVertex2f(x1,y1);
structRectangle
floatxmin,xmax,ymin,ymax;
};
Rectanglerect;
intx0,y0,x1,y1;
intCompCode(intx,inty,Rectanglerect)
intcode=0x00;
if(y<
rect.ymin)
code=code|4;
if(y>
rect.ymax)
code=code|8;
if(x>
rect.xmax)
code=code|2;
if(x<
rect.xmin)
code=code|1;
returncode;
intcohensutherlandlineclip(Rectanglerect,int&
x0,int&
y0,int&
x1,int&
y1)
intaccept,done;
floatx,y;
accept=0;
done=0;
intcode0,code1,codeout;
code0=CompCode(x0,y0,rect);
code1=CompCode(x1,y1,rect);
do{
if(!
(code0|code1))
accept=1;
done=1;
elseif(code0&
code1)
else
if(code0!
=0)
codeout=code0;
codeout=code1;
if(codeout&
LEFT_EDGE){
y=y0+(y1-y0)*(rect.xmin-x0)/(x1-x0);
x=(float)rect.xmin;
elseif(codeout&
RIGHT_EDGE){
y=y0+(y1-y0)*(rect.xmax-x0)/(x1-x0);
x=(float)rect.xmax;
BOTTOM_EDGE){
x=x0+(x1-x0)*(rect.ymin-y0)/(y1-y0);
y=(float)rect.ymin;
TOP_EDGE){
x=x0+(x1-x0)*(rect.ymax-y0)/(y1-y0);
y=(float)rect.ymax;
if(codeout==code0)
x0=x;
y0=y;
x1=x;
y1=y;
}while(!
done);
if(accept)
LineGL(x0,y0,x1,y1);
returnaccept;
voidmyDisplay()
glRectf(rect.xmin,rect.ymin,rect.xmax,rect.ymax);
rect.xmin=100;
rect.xmax=300;
rect.ymin=100;
rect.ymax=300;
x0=450,y0=0,x1=0,y1=450;
printf("
Presskey'
c'
toClip!
\nPresskey'
r'
toRestore!
\n"
voidkeyboard(unsignedcharkey,intx,inty)
switch(key)
case'
:
cohensutherlandlineclip(rect,x0,y0,x1,y1);
glutPostRedisplay();
break;
case
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 计算机 图形学 OpenGL 实验 14