《-计算机图形学实验报告.docx》由会员分享,可在线阅读,更多相关《-计算机图形学实验报告.docx(73页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、-计算机图形学实验报告计算机图形学实验报告姓名:学号:班级:时间: 2016年12月实验一 OpenGL编程与图形绘制1 .实验目的了解OpenGL编程,并熟悉OpenGL的主要功 能、绘制流程和基本语法。学会配置OpenGL环 境,并在该环境中编程绘图。2 .实验内容OpenGL的主要功能:模型绘制、模型观察、 颜色模式、光照应用、图像效果增强、位图和图 像处理、纹理映射、实时动画和交互技术。OpenGL的绘制流程分为两个方面:一个完 整的窗口系统的OpenGL图形处理系统的结构 为:最底层为图形硬件,第二层为操作系统,第 三层为窗口系统,第四层为OpenGL,最上面的 层为应用软件;Ope
2、nGL命令将被放在一个命令 缓冲区中,这样命令缓冲区中包含了大量的命 令、顶点数据和纹理数据。当缓冲区被清空时, 缓冲区中的命令和数据都将传递给流水线的下 一个阶段。OpenGL的基本语法中相关库有:OpenGL核 心库:gl、OpenGL实用程序库:glu、OpenG编 程辅助库:aux、OpenGL实用程序工具包(OpenGL utility toolkit, GLUT): glut Windows 专用 库:WgloOpenGL的基本语法中命名规则为:OpenGL 函数都遵循一个命名约定,即采用以下格式: 库前缀X根命令X可选的参数个数X可选的参 数类型。了4了上述基础知识后,配置好Op
3、enGL环 境,然后在该环境中编程练习图形的绘制,本次 实验主要是对点的绘制、直线的绘制和多边形面 的绘制。3 .实验代码及结果3.1 点的绘制:#include void Initial(void)glClearColor (1. Of, 1. Of, 1. Of, 1. Of); / 设置窗口背景颜色为白色glMatrixMode(GL_PROJECTION);/指定设置投影参数glu0rtho2D (0. 0, 200. 0, 0. 0, 150. 0);/设置投影参数 )void Display(void)(glClear(GL_COLOR_BUFFER_BIT);/用当前背景颜色填充
4、窗口glColor3f (1. Of, 0. Of, 0. Of);/设置当前的绘图颜色为红/ glRectf (50. Of, 100. Of, 150. Of, 50. Of); 绘制一个矩形glPointSize (10);三个点glBegin(GL_POINTS);glColor3f(1.0f, 0. Of, 0. Of);glVertex2i(2, 148);glVertex2i(100,75);glVertex2i(198, 2);glEnd ();glFlushO;/清空OpenGL命令缓冲区,执行OpenGL程序)int main(int argc, char*argv)(gl
5、utlnit(&argc, argv);glutlnitDisplayMode(GLUT_SINGLE|GLUT_RGB);初始化窗口的显示模式glutlnitWindowSize(400, 300);设置窗口的尺寸glutlnitWindowPosition(100, 120);设置窗口位置glutCreateWindow (,z 矩 形 ”);创建一个名为矩形的窗口glutDisplayFunc(Display);设置当前窗口的显示回调函数Initial ();完成窗口初始化glutMainLoop();完成窗口 GLUT事件处理循环 return 0;运行结果:3. 2直线的绘制:#in
6、cludevoid Initial(void)(glClearColor(l. Of, 1. Of, 1. Of, 1. Of); / 设置窗口背景颜色为白色glMatrixMode(GL_PROJECTION);/指定设置投影参数glu0rtho2D (0. 0, 200. 0, 0. 0, 150. 0);/设置投影参数void Display(void)(glClear(GL_COLOR_BUFFER_BIT);/用当前背景颜色填充窗口glColor3f(l. Of, 0. Of, 0. Of);/设置当前的绘图颜色为红色/ glRectf (50. Of, 100. Of, 150.
7、Of, 50. Of); 绘制一个矩形glBegin(GL_LINE_LOOP); 五角星glVertex2i(10, 10);glVertex2i(30, 35);glVertex2i(50, 10);glVertex2i (5, 25);glVertex2i (55, 25);glEnd ();glFlushO;/清空OpenGL命令缓冲区,执行OpenGL程序 )int main(int argc, char*argv)(glutlnit(&argc, argv);glutlnitDisplayMode(GLUT_SINGLE|GLUT_RGB);初始化窗口的显示模式 glutlnitW
8、indowSize(400, 300);设置窗口的尺寸glutInitWindowPosition(100, 120);设置窗口位置glutCreateWindow (,z矩 形 ”);创建一个名为矩形的窗口 glutDisplayFunc(Display);设置当前窗口的显示回调函数 Initial ();完成窗口初始化 glutMainLoop();完成窗口 GLUT事件处理循环 return 0;运行结果:矩形BE3. 3多边形面的绘制:#include void Initial(void) (glClearColor(l. Of, 1. Of, 1. Of, 1. Of); / 设置窗
9、口背景颜色为白色glMatrixMode(GL_PROJECTION);/指定设置投影参数glu0rtho2D(0. 0, 200. 0, 0. 0, 150. 0);/设置投影参数 )void Display(void)glClear(GL_COLOR_BUFFER_BIT);/用当前背景颜色填充窗口glColor3f(l. Of, 0. Of, 0. Of);/设置当前的绘图颜色为红色/ glRectf (50. Of, 100. Of, 150. Of, 50. Of);绘制一个矩形glBegin (GL_TRIANGLES); 等边三角形glVertex2f (0. 0, 0. 0);
10、glVertex2f(15, 25. 95);glVertex2f(30, 0);glEnd ();glFlushO;/清空OpenGL命令缓冲区,执行OpenGL程序int main(int argc, char*argv)(glutlnit(&argc, argv);glutlnitDisplayMode(GLUT_SINGLE|GLUT_RGB);初始化窗口的显示模式glutlnitWindowSize(400, 300);设置窗口的尺寸glutlnitWindowPosition(100, 120);设置窗口位置glutCreateWindow (,z矩 形 ”);创建一个名为矩形的窗
11、口 glutDisplayFunc(Display);设置当前窗口的显示回调函数 Initial ();完成窗口初始化 glutMainLoop();完成窗口 GLUT事件处理循环 return 0;运行结果:实验二直线绘制实验1 .实验目的为了进一步熟悉OpenGL编程,了解基本图 形生成算法中的直线绘制,学会直线绘制算法中 最常用的三种算法:数值微分法、中点画线算法 和 Bresenham 算法。2 .实验内容(一)数值微分法数值微分法直接从直线的微分方程生成直 线。给定直线的两端点:PO (XO, Y0)和P1(X1, Y1), 得到直线的微分方程dy/dx= y/ x=(Yl-YO)/
12、(Xl-XO)=ko数值微分算法的原理是,由于直线的一阶导 数是连续的,而且和是成比例的,因此 通过在当前位置(Xi, Yi)分别加上两个小增量 和 4y( e为无穷小的正数)来求下一点 (X(i+l),Y(i+l)的 x, y 坐标。(二)中点画线算法给定直线的两端点:PO (XO, Y0)和 Pl (XI, Y1),可得到直线方程 F (x, y) =y-kx-b=O 且 k=Ay/Ax= (Yl-YO) / (Xl-XO) o绘图过程如下:O .输入直线的两端点PO (XO, Y0)和Pl(Xl,Yl)o。.计算初始值*, y, d= x-2 y, x=XO, y=YO.。.绘制点(x,
13、y)。判断d的符号,若d0, 则(x, y)更新为(x+l,y+l),同样将e更新为e-2 x;否则(x, y)更新为(x+l,y)。.当直线没有画完时,重复步骤。和O; 否则结束。3.实验代码及结果3.1数值微分算法编程绘制直线代码:#include#includevoid Initial(void)glClearColor (1. Of, 1. Of, 1. Of, 1. Of); / 设置窗口背景颜色为白色glMatrixMode(GL_PROJECTION);/指定设置投影参数glu0rtho2D(0. 0, 200. 0, 0. 0, 150. 0);/设置投影参数 void Dis
14、play(void)(glClear(GL_COLOR_BUFFER_BIT);/用当前背景颜色填充窗口glColor3f(l. Of, 0. Of, 0. Of);/设置当前的绘图颜色为红色 glBegin(GL_LINES);int x0=10;int y0=20;int xl=30;int yl=40;int color=10;int dx, dy, epsl, k;float x, y, xlncre, ylncre;dx=xl-x0;dy=yl-yO;x=x0;y=yO;/if(abs(dx)abs(dy) epsl=abs(dx);else epsl=abs(dy);xlncre=
15、(float)dx/(float) epsl;ylncre=(float)dy/(float)epsl;for (k=0;k=epsl;k+) (glVertex2i (int (x+0. 5), (int) (y+0. 5);x+=xlncre;y+=ylncre;glEnd ();glFlushO;/清空OpenGL命令缓冲区,执行OpenGL程序int main(int argc, char*argv)(glutlnit(&argc, argv);glutlnitDisplayMode(GLUT_SINGLE|GLUT_RGB); 初始化窗口的显示模式glutlnitWindowSize
16、(400, 300);设置窗口的尺寸glutInitWindowPosition(100, 120);设置窗口位置glutCreateWindow (,z 矩 形 ”);创建一个名为矩形的窗口 glutDisplayFunc(Display);设置当前窗口的显示回调函数 Initial ();完成窗口初始化 glutMainLoopO ;完成窗口 GLUT事件处理循环 return 0;实验结果:矩形BE2. 2中点画线算法编程绘制直线代码:#include#include void Initial(void) (glClearColor(l. Of, 1. Of, 1. Of, 1. Of)
17、; / 设置窗口背景颜色为白色glMatrixMode(GL_PROJECTION);/指定设置投影参数glu0rtho2D (0. 0, 200. 0, 0. 0, 150. 0);/设置投影参数 )void Display(void)(glClear(GL_COLOR_BUFFER_BIT);/用当前背景颜色填充窗口glColor3f (1. Of, 0. Of, 0. Of);/设置当前的绘图颜色为红色 glBegin(GL_POINTS);int x0=50;int y0=20;int xl=100;int yl=120;int color=10;int dx, dy, d, Upln
18、cre, Downlncre, x, y;if (x0xl)(x=xl;xl=x0;x0=x;y=yl;yl=y0;y0=y;x=x0;y=yO;dx=xl-x0;dy=yl-yO;d=dx-2*dy;Uplncre=2*dx-2*dy; Downlncre=2*dy;while(x=xl)glVertex2i (x, y);x+;if(d0)y+;d+=UpIncre;else d+=DownIncre;glEnd ();glFlushO;/清空OpenGL命令缓冲区,执行OpenGL程序int main(int argc, char*argv)(glutlnit(&argc, argv);
19、glutlnitDisplayMode(GLUT_SINGLE|GLUT_RGB);初始化窗口的显示模式glutlnitWindowSize(400, 300);设置窗口的尺寸glutlnitWindowPosition(100, 120);设置窗口位置glutCreateWindow (,z 矩 形 ”);创建一个名为矩形的窗口 glutDisplayFunc(Display);设置当前窗口的显示回调函数 Initial ();完成窗口初始化 glutMainLoop();完成窗口 GLUT事件处理循环 return 0;实验结果:矩形目回区I2. 3Bresenham算法编程绘制直线代码:
20、 include #include void Initial(void)glClearColor(l. Of, 1. Of, 1. Of, 1. Of);/设置窗口背景颜色为白色glMatrixMode(GL_PROJECTION); 指定 设置投影参数glu0rtho2D(0. 0, 200. 0, 0. 0, 150. 0); / 设 置投影参数 void Display(void)glClear (GL_COLOR_BUFFER_BIT); / 用当前 背景色填充窗口glColor3f(l. Of, 0. Of, 0. Of); 设置当 前的绘图颜色为红色/Bresenham 算法 gl
21、Begin(GL_POINTS);int xO = 10; int yO = 20; int xl = 90; int yl =90;int color=10;int x, y, dx, dy, e;dx = xl-xO;dy = yl-yO;e=-dx;x=x0;y=yO;while(x0)y+;e=e-2*dx;)glEndO ;glFlushO ; 清空OpenGL命令缓冲区,执 行OpenGL程序int main(int argc, char*argv)glutlnit(&argc, argv);glutlnitDisplayMode(GLUT_SINGLE|GLUT_RGB); 初始
22、化窗口的现实模式glutlnitWindowSize (400, 300); / 设置窗 口的尺寸glutInitWindowPosition(100,200); / 设 置窗口的位置glutCreateWindow (点”);创建一个名为矩形的窗口glutDisplayFunc (Display); 设置当前窗 口的显示函数Initial ();完成窗口的初始化glutMainLoopO ; 启动主 GLUT 事件 处理循环return 0;实验结果:BE实验三圆绘制实验1 .实验目的2 .实验内容(一)八分法画圆圆心位于原点的圆有4条对称轴 x=0, y=0, y=x, y=-x。若已知圆
23、上任一点(x, y), 可以得到其在圆周上关于四条对称轴的另外7 个点(y, x), (-x, y), (-x, -y), (-y, -x), (y, -x), (x, -y )o(二)中点Bresenham画圆算法算法步骤如下:。输入圆的半径R。计算初始值d=l-R, x=0, y=Ro。绘制点(x, y)及其在八分圆中的另外7个 对称点。判断d的符号。若d0,则先将d更新为 d+2x+3,再将(x, y)更新为(x+1, y);否则先将d 更新为d+2(x-y)+5,再将(x,y)更新为 (x+1, y-1) o。当xy时,重复步骤Q和O;否则结束。(三)椭圆的中点Bresenham算法算
24、法步骤如下:输入椭圆的长半轴a和短半轴bo 计 算 初 始 值 d=b2+a2 (-b+0. 25), x=0, y=bo绘制点(x, y)及其在四分象限上的另外三 个对称点。判断d的符号。若d=0,则先将d更新为 d+b-2 (2x+3),再将(x, y)更新为(x+1, y);否则先 将 d 更新为 d+b-2 (2x+3) +a2 (-2y+2),再将(x, y) 更新为(x+1, y-1) o当了2&+1)6-2-0.5)时,重复步骤 和;否则转到步骤。用上半部分计算的最后点(x, y)来计算下 半 部 分 中 d 的 初 值 d=b,2 (x+0. 5厂2+a2 (y-1 厂2-a为
25、K20绘制点(X, y)及其在四分象限上的另外三 个对称点。判断d的符号。若d=0时,重复步骤和否则结束。3 .实验代码及结果3.1 八分法画圆程序代码:#include#includevoid Initial(void)(glClearColor(l. Of, 1. Of, 1. Of, 1. Of); / 设置窗口背景颜色为白色glMatrixMode(GL_PROJECTION);/指定设置投影参数glu0rtho2D (0. 0, 200. 0, 0. 0, 150. 0);/设置投影参数) void CirclePoint(int x, int y, int color) glVer
26、tex2i(x+50, y+50);glVertex2i(y+50, x+50);glVertex2i(-y+50, x+50);glVertex2i(-x+50, y+50);glVertex2i(-x+50, -y+50);glVertex2i(-y+50, -x+50);glVertex2i(y+50, -x+50);glVertex2i(x+50, -y+50);void Display(void)(glClear(GL_COLOR_BUFFER_BIT);/用当前背景颜色填充窗口glColor3f(l. Of, 0. Of, 0. Of); 设置当前 的绘图颜色为红色glPointS
27、ize(lO);glBegin(GL_POINTS);CirclePoint(10, 20, 20);glEnd ();glFlushO;/清空OpenGL命令缓冲区,执行OpenGL程序int main(int argc, char*argv)(glutlnit(&argc, argv);glutlnitDisplayMode(GLUT_SINGLE|GLUT_RGB);初始化窗口的显示模式 glutlnitWindowSize(400, 300);设置窗口的尺寸glutInitWindowPosition(100, 120);设置窗口位置glutCreateWindow (z/ 矩 形 ”
28、);创建一个名为矩形的窗口 glutDisplayFunc(Display);设置当前窗口的显示回调函数 Initial ();完成窗口初始化 glutMainLoop();完成窗口 GLUT事件处理循环 return 0;实验结果:3. 2中点Bresenham算法绘制圆代码 #include #include void Initial(void) (glClearColor(l. Of, 1. Of, 1. Of, 1. Of); / 设置窗口背景颜色为白色glMatrixMode(GL_PROJECTION);/指定设置投影参数glu0rtho2D (0. 0, 200. 0, 0. 0
29、, 150. 0);/设置投影参数void CirclePoint (int x, int y, int color) glVertex2i(x+50, y+50);glVertex2i(y+50, x+50);glVertex2i(-y+50, x+50);glVertex2i(-x+50, y+50);glVertex2i(-x+50, -y+50);glVertex2i(-y+50, -x+50);glVertex2i(y+50, -x+50);glVertex2i(x+50, -y+50);void MidBresenhamCircle(int r, int color) (int x
30、, y, d;x=0;y=r;d=l-r;while(x=y)CirclePoint (x, y, color);if(d0)d+=2*x+3;else(d+=2*(x-y)+5;y;x+;void Display(void)(glClear(GL_COLOR_BUFFER_BIT);/用当前背景颜色填充窗口glColor3f(l. Of, 0. Of, 0. Of); 设置当前 的绘图颜色为红色glPointSize(3);glBegin(GL_POINTS);MidBresenhamCircle(20, 10);glEnd ();glFlushO;/清空OpenGL命令缓冲区,执行Open
31、GL程序int main(int argc, char*argv)(glutlnit(&argc, argv);glutlnitDisplayMode(GLUT_SINGLE|GLUT_RGB);初始化窗口的显示模式glutlnitWindowSize(400, 300);设置窗口的尺寸glutInitWindowPosition(100, 120);设置窗口位置glutCreateWindow C 矩 形 ”);创建一个名为矩形的窗口 glutDisplayFunc(Display);设置当前窗口的显示回调函数 Initial ();完成窗口初始化 glutMainLoop();完成窗口 G
32、LUT事件处理循环 return 0;实验结果:3. 3中点Bresenham算法绘制椭圆代码:#include#include void Initial(void) (glClearColor(l. Of, 1. Of, 1. Of, 1. Of); / 设置窗口背景颜色为白色/glMatrixMode(GL_PROJECTION);指定设置投影参数glu0rtho2D(0. 0, 200. 0, 0. 0, 150. 0);/设置投影参数 void MidBresenhamEllipse(int a, int b, int color) (int x, y;float dl, d2;x=0
33、;y=b;dl=b*b+a*a*(-b+0. 25);glVertex2i(x+50, y+50);glVertex2i(-x+50, -y+50);glVertex2i(-x+50, y+50);glVertex2i(x+50, -y+50);while(b*b*(x+1) a*a*(y-0. 5)(if(dl0) if(d2=0)(d2+=b*b*(2*x+2)+a*a*(-2*y+3);x+;y;else d2+=a*a*(-2*y+3);)glVertex2i(x+50, y+50);glVertex2i(-x+50, -y+50);glVertex2i(-x+50, y+50);gl
34、Vertex2i(x+50, -y+50);void Display(void)(glClear(GL_COLOR_BUFFER_BIT);/用当前背景颜色填充窗口glColor3f(l. Of, 0. Of, 0. Of); 设置当前 的绘图颜色为红色glPointSize(3);glBegin(GL_POINTS);MidBresenhamEllipse(40, 25, 10);glEnd ();glFlushO;/清空OpenGL命令缓冲区,执行OpenGL程序 int main(int argc, char*argv)glutlnit(&argc, argv);glutlnitDisp
35、layMode(GLUT_SINGLE|GLUT_RGB);初始化窗口的显示模式glutlnitWindowSize(400, 300);设置窗口的尺寸glutlnitWindowPosition(100, 120);设置窗口位置glutCreateWindow C 矩 形 ”);创建一个名为矩形的窗口 glutDisplayFunc(Display);设置当前窗口的显示回调函数 Initial ();完成窗口初始化 glutMainLoop();完成窗口 GLUT事件处理循环return 0;实验结果:BE矩形实验四填充算法实验1 .实验目的掌握用扫描线种子填充法,实现扫描线种子填 充算法填
36、充任一多边形区域的程序2 .实验内容算法步骤如下:(1)种子像素入栈。(2)执行如下三步操作:。栈顶像素出栈。填充出栈像素所在扫描线的连续像素段, 从出栈的像素开始沿扫描线向左和向右填充,直 到遇到边界像素为止,即每出栈一个像素,就对 包含该像素的整个扫描线区间进行填充,并且记 录下此时扫描线区间的x坐标范围xl, x2 o。分别检查上、下两条扫描线上位于xl, x2 坐标区间内的未被填充的连续水平像素段,将每 个连续像素段的最左像素取作种子像素压人栈 堆。(3)检查栈是否为空,若栈非空重复执行步 骤(2),若栈为非空则结束。3 .实验代码及结果代码:include gl/gluth#incl
37、ude math, h”#include stdlib. h#include “conio. h#include typedef float Color 3;struct Point(GLint x;GLint y;);std:stack stk;void init(void)(glClearColor (1. 0, 1. 0, 1. 0, 1. 0) ;/Setdisplay-window color white.glMatrixMode(GL_PR0JECTI0N);glu0rtho2D(0. 0, 400. 0, 0. 0, 400. 0);void setPixel (GLint x,
38、 GLint y); 种子像素 坐标void setPixel (Point cur_point)(glBegin(GL_POINTS);glVertex2i(cur_point. x, cur_point. y);glEnd ();glFlushO ;void getPixel(Point cur_point, Color c)(glReadPixels (cur_point. x, cur_point. y, 1, 1, GL_RGB, GL_FL0AT, c);bool rgbColorEqual(Color cl,Color c2)(cl颜色数据与c2颜色数据,当正负误差不 超过0.
39、0001时,返回值为1,否则为0if(abs(cl0-c20)0. 001) | | (abs(cll-c2l)0. 001) | |(abs(cl2-c22)0. 001) return 0;else return 1;int FillLineRegion(Point cur_point, Color f illColor, Color borderColor, int direction) (int count=0;Color interiorColor;glColor3f(fillColor0, fillColorl, fillC olor 2);getPixel(cur_point,
40、interiorColor);while(!(rgbColorEqual(interiorColor, borde rColor)&!(rgbColorEqual(interiorColor, f illColor)这个判断保证读取的像素的颜色数据与 边界颜色还有填充颜色数据在数值上相差较大即当正读取像素不是多边形边界,且也没 有被填充,则执行以下花括号内的操作setPixel(cur_point); /setcolot of pixel to fillColor. 为坐标为(x, y)的像素 上色if(direction=0)cur_point. x+;elsecur_point. x;ge
41、tPixel(cur_point, interiorColor);count+;return count;int IsPixelValid(Point cur_point, Color fillColor, Color borderColor) (Color interiorColor;getPixel (curjpoint, interiorColor);if(!(rgbColorEqual(interiorColor, border Color)&!(rgbColorEqual(interiorColor, fi UColor)return 1;elsereturn 0;void SearchLineNewSeed(int xLeft, int xRight, int y, Color fillColor, Color borderColor) 在种子像素所在扫描线上一条 或下一条是扫描线寻找新种子像素 (int xt=xLeft;int seed_left=-l;Point seed_point;Point temp_point;while(xt=xRight) seed_left=-l;temp_point. x=xt;temp_point. y=y;whi