1、计算机图形学作业实验报告计 算 机 图 形 学实 验 报 告班 级: 学 号: 姓 名: 指导教师: 完成日期: 实验一:多边形填充1、实验目的 了解多边形属性,熟悉相关函数的调用。二、实验内容步骤和实现:首先进行初始化工作,进行显示模式(单缓冲区)和窗口等设定,主要实现根据两个函数,一个是指定场景绘制函数,glutDisplayFunc(Paint),paint函数中设置了两个三角形,一个填充,一个不填充。用到了启用多边形点画模式glEnable(GL_POLYGON_STIPPLE)的函数,和指定多边形点画模式(填充) glPolygonStipple(fly)的函数。另外一个就是循环执行
2、OpenGl命令的glutMainLoop()函数。三、实验结果四、源程序/ POLY_STIPPLE.C#include void makeObject() / 定义一个三角形 glBegin(GL_TRIANGLES); / 开始定义三角形 / 按逆时针方向指定三角形的顶点坐标 glVertex2f(-0.95, -0.95); glVertex2f(0.95, -0.95); glVertex2f(0, 0.95); glEnd(); / 三角形定义结束void display() GLsizei w = glutGet(GLUT_WINDOW_WIDTH); / 程序窗口宽度 GLsi
3、zei h = glutGet(GLUT_WINDOW_HEIGHT); / 程序窗口高度 GLubyte fly = / 第二个三角形点画模式的mask值 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, / 0X03, 0X80, 0X01, 0XC0, 0X06, 0XC0, 0X03, 0X60, / 0X04, 0X60, 0X06, 0X20, 0X04, 0X30, 0X0C, 0X20, / 0X04, 0X18, 0X18, 0X20, 0X04, 0X0C, 0X30, 0X20, / 0X04, 0X06, 0X60, 0X2
4、0, 0X44, 0X03, 0XC0, 0X22, / 0X44, 0X01, 0X80, 0X22, 0X44, 0X01, 0X80, 0X22, / 0X44, 0X01, 0X80, 0X22, 0X44, 0X01, 0X80, 0X22, / 0X44, 0X01, 0X80, 0X22, 0X44, 0X01, 0X80, 0X22, / 0X66, 0X01, 0X80, 0X66, 0X33, 0X01, 0X80, 0XCC, / 0X19, 0X81, 0X81, 0X98, 0X0C, 0XC1, 0X83, 0X30, / 0X07, 0XE1, 0X87, 0XE
5、0, 0X03, 0X3F, 0XFC, 0XC0, / 0X03, 0X31, 0X8C, 0XC0, 0X03, 0X33, 0XCC, 0XC0, / 0X06, 0X64, 0X26, 0X60, 0X0C, 0XCC, 0X33, 0X30, / 0X18, 0XCC, 0X33, 0X18, 0X10, 0XC4, 0X23, 0X08, / 0X10, 0X63, 0XC6, 0X08, 0X10, 0X30, 0X0C, 0X08, / 0X10, 0X18, 0X18, 0X08, 0X10, 0X00, 0X00, 0X08 ; glClear(GL_COLOR_BUFFE
6、R_BIT); / 清除颜色缓冲区 glViewport(0, 0, w / 2, h); / 第一个视口,显示第一个三角形 glColor3f(1, 1, 1); / 设置颜色,白色,默认值 makeObject(); / 第一个三角形 glViewport(w / 2, 0, w / 2, h); / 第二个视口,显示第二个三角形 glColor3f(1, 0, 0); / 设置颜色,红色 glEnable(GL_POLYGON_STIPPLE); / 启用多边形点画模式 glPolygonStipple(fly); / 指定多边形点画模式(填充) makeObject(); / 第二个三
7、角形 glDisable(GL_POLYGON_STIPPLE); / 关闭多边形点画模式 glFlush(); / 强制OpenGL命令序列在有限的时间内完成执行int main() glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); / 设置程序窗口的显示模式(单缓冲区、RGBA颜色模型) glutInitWindowPosition(100, 100); / 程序窗口的位置 glutInitWindowSize(300, 150); / 程序窗口的大小 glutCreateWindow(一个填充多边形的例子!); / 窗口的标题 glutDispl
8、ayFunc(display); / 指定场景绘制函数 glutMainLoop(); / 开始循环执行OpenGL命令实验二:基本图元绘制2、实验目的 了解OpenGL图形软件包绘制图形的基本过程及其程序框架,并在已有的程序框架中添加代码实现直线和圆的生成算法,演示直线和圆的生成过程,从而加深对直线和圆等基本图形生成算法的理解。二、实验内容 实验操作和步骤:本次实验主要的目的是为了掌握基本画线和画圆算法,中点画线算法的步骤是(考虑0m0,则下一点为(xk+1,yk),且Pk+1=Pk+2a; 若pk=0,则下一点为(xk+1,yk+1),且pk+1=pk+(2a+2b).4, 重复步骤3,共
9、b次。中点画圆的算法的步骤是:1,输入圆半径r和圆心(xc,yc),并得到圆心在原点的圆周上的第一点:(x0,y0)=(0,r).2,计算决策参数的初始值:p0=1-r.3,从k=0开始,对每个xk,完成下列检测:若pk=0,则下一点是(Xk+1,Yk-1),且p(k+1)=Pk+2X(k+1)+1-2Y(k+1)其中,2X(k+1)+1=2Xk+1+2,2Y(k+1)=2Yk-24,确定其他七个八分圆中的对称点5,将计算出来的每个像素位置(x,y)变换到待画圆上: X=x+xc,y=y+yc6,重复3-5,直到x=y三、实验结果1-1 中点画线算法演示:1-2 中点画圆算法演示四、源程序中点
10、画线算法程序:/ xtGL.h#pragma once#include #include / 全局变量说明static void(*_xtViewportFunc)(int, int, int, int);/ 指向用户自定义的构建视口和相关变换的函数/ 函数说明int main(int argc, char *argv);void xtMain(int argc, char *argv); / xtGL的入口函数static void xtDefaultInit(); / 默认初始化void xtViewportFunc(void Func(int, int, int, int);/ 指定用户
11、自定义的构建视口和相关变换的函数static void xtDefaultViewport(int x, int y, int w, int h);/ 构建视口和相关变换的默认函数static void xtDefaultReshape(int w, int h); / 默认窗口变化回调函数static void xtDefaultPaint(void); / 默认场景绘制函数static void xtView(GLuint m, GLuint n, int i, int j); / 子区间函数void xtViewInit(int m, int n); / 初始化子区间个数和大小void
12、xtViewBegin(int i, int j); / 第i行第j列子区间void xtViewEnd(); / 结束子区间内对象定义/ 函数实现int main(int argc, char *argv) xtDefaultInit(); / 默认初始化 xtMain(argc, argv); / xtGL的入口函数 glutMainLoop(); / 开始循环执行OpenGL命令/ 默认初始化static void xtDefaultInit() int scw, sch, w, h; / 屏幕宽度和高度,程序窗口的宽度和高度 glutInitDisplayMode(GLUT_DOUBL
13、E | GLUT_RGBA | GLUT_DEPTH); / 显示模式为:双缓冲区,RGBA颜色模式,使用深度缓冲器 / 只有一次生效,使用该框架只能使用这里规定的显示模式 scw = glutGet(GLUT_SCREEN_WIDTH); / 屏幕宽度 sch = glutGet(GLUT_SCREEN_HEIGHT); / 屏幕高度 h = sch / 2, w = h * 4 / 3; / 程序窗口的高度和宽度 glutInitWindowPosition(scw - w) / 2, (sch - h) / 2); glutInitWindowSize(w, h); / 默认窗口高度为屏
14、幕高度的一半,宽高比为4:3,位于屏幕中央 glutCreateWindow(_argv0); / 窗口的默认标题 glEnable(GL_DEPTH_TEST); / 打开深度测试 xtViewportFunc(xtDefaultViewport); / 构建视口和相关变换的默认函数 glutReshapeFunc(xtDefaultReshape); / 默认的窗口变化回调函数 glutDisplayFunc(xtDefaultPaint); / 默认的场景绘制函数/ 指定用户自定义的构建视口和相关变换的函数void xtViewportFunc(void Func(int, int, i
15、nt, int) _xtViewportFunc = Func;/ 构建视口和相关变换的默认函数static void xtDefaultViewport(int x, int y, int w, int h) float aspect; if(h = 0) return ; aspect = 1.0 * w / h; / 窗口横纵比 glViewport(x, y, w, h); / 定义视口 / 默认投影矩阵,y向观察范围为60度,近平面为1,远平面为1000 glMatrixMode(GL_PROJECTION); / 当前矩阵模式为投影矩阵 glLoadIdentity(); / 当前
16、矩阵为单位矩阵 gluPerspective(60, aspect, 1, 1000); / 定义投影矩阵,参数依次为:y-z夹角;x/y;近平面;远平面 glTranslated(0, 0, - 2); / 远移2单位,保证z坐标可以使用+1 glMatrixMode(GL_MODELVIEW); / 当前矩阵模式为视图造型矩阵 glLoadIdentity(); / 当前矩阵为单位矩阵/ 默认窗口变化回调函数(构建视口和相关变换)static void xtDefaultReshape(int w, int h) _xtViewportFunc(0, 0, w, h);/ 默认场景绘制函数
17、void xtDefaultPaint() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); / 清除颜色缓存和深度缓存 glutSwapBuffers(); / 交换颜色缓存/ 子区间函数,内部使用static void xtView(GLuint m, GLuint n, int i, int j) int w, h, x, y; / 子区间的宽度和高度以及子区间的左下角坐标 static GLuint svm = 1, svn = 1; / 子区间个数 static GLuint maxRow = 0; / 最大行号 if(i 0 |
18、 j 1) / 只有当子区间的个数大于1时,才构建视口和相关变换 w = glutGet(GLUT_WINDOW_WIDTH) / svn; / 子区间宽度 h = glutGet(GLUT_WINDOW_HEIGHT) / svm; / 子区间高度 x = j * w; y = (maxRow - i) * h; / 第i行j列子区间的左下位置 _xtViewportFunc(x, y, w, h); / 构建视口和相关变换 glPushMatrix(); / 保存当前矩阵 glPushAttrib(GL_ALL_ATTRIB_BITS); / 保存所有当前属性值/ 初始化子区间个数和大小v
19、oid xtViewInit(int m, int n) xtView(m, n, - 1, - 1);/ 第i行第j列子区间(找到该子区间的位置,开始定义对象)void xtViewBegin(int i, int j) xtView(0, 0, i, j);/ 结束子区间内的对象定义(恢复当前属性值和当前矩阵)void xtViewEnd() glPopAttrib(); glPopMatrix();/Demo.h#pragma once#include #include xtGlu.hvoid init() glEnable(GL_POINT_SMOOTH); glEnable(GL_L
20、INE_SMOOTH); glEnable(GL_POLYGON_SMOOTH);void axis(int x1, int y1, int x2, int y2) int x, y; glEnable(GL_LINE_STIPPLE); glLineStipple(1, 0XCCCC); glLineWidth(1); glColor3f(0.5, 0.5, 0.5); glBegin(GL_LINES); for (x = x1; x = x2; +x) glVertex2i(x, y1), glVertex2i(x, y2); for (y = y1; y = y2; +y) glVer
21、tex2i(x1, y), glVertex2i(x2, y); glEnd(); glDisable(GL_LINE_STIPPLE); for (x = x1; x = x2; +x) xtStrokeText(x, y1 - 0.5, 0.003, %d, x); for (y = y1; y = y2; +y) xtStrokeText(x1 - 0.75, y, 0.003, %d, y);#include #include Demo.hvoid Mid_Line1(int x1, int y1, int x2, int y2) int a, b, c, x, y, p, _2a,
22、_2a_2b; if(x2 x1) int temp; temp = x1, x1 = x2, x2 = temp; temp = y1, y1 = y2, y2 = temp; a = y1 - y2, b = x2 - x1; _2a = 2 * a , _2a_2b = _2a + 2 * b; y = y1, p = 2 * a + b; for(x = x1; x 0) p = p + _2a; else +y, p += _2a_2b; /void reshape(int w, int h) glViewport(0, 0, w, h); glLoadIdentity(); glu
23、Ortho2D(19, 31, 9, 21);/void display() glClearColor(1, 1, 1, 0); glClear(GL_COLOR_BUFFER_BIT); axis(20, 10, 30, 18); glLineWidth(3); glColor3f(0, 0, 1); glBegin(GL_LINES); glVertex2i(20, 10), glVertex2i(30, 18); glEnd(); glPointSize(15); glColor3f(1, 0, 0); glBegin(GL_POINTS); Mid_Line1(20, 10, 30,
24、18); glEnd(); glFlush();/int main() glutInitWindowSize(400, 400); glutCreateWindow(中点画线算法演示!); glutReshapeFunc(reshape); init(); glutDisplayFunc(display); glutMainLoop();中点画圆算法程序:(说明:引用了Demo.h和xtGlu.h两个头文件)#include #include Demo.hvoid Mid_Circle1(int r) int x, y, p, _2x_1, _2y; x = 0, y = r, p = 1 -
25、 r, _2x_1 = 1, _2y = 2 * r; glVertex2i(x, y), glVertex2i(y, x); while(x y) +x, _2x_1 += 2; if(p 0) x -= e * y, y += e * x, glVertex2d(x, y);void display() glClearColor(1, 1, 1, 0); glClear(GL_COLOR_BUFFER_BIT); axis(0, 0, 10, 10); glLineWidth(2); glColor3f(0, 0, 1); glBegin(GL_LINE_STRIP); myArc(10,
26、 1.57); glEnd(); glPointSize(15); glColor3f(1, 0, 0); glBegin(GL_POINTS); Mid_Circle1(10); glEnd(); glFlush();/int main() glutInitWindowSize(400, 400); glutCreateWindow(中点画圆算法演示!); glutReshapeFunc(reshape); init(); glutDisplayFunc(display); glutMainLoop();实验三:太阳系模型动画一、实验目的利用OpenGL图形软件包,建立太阳、地球和月亮的运动
27、模型;增加光照系统,模拟太阳、地球和月亮的光照环境;并利用双缓存技术,用动画方式显示模型。以加深学生对几何变换、投影变换以及观察变换的理解,并提高学生利用图形软件包绘制图形的能力。 二、实验内容步骤和实现:首先进行初始化工作,进行显示模式和窗口,设置光源等设定,主要实现根据两个函数,一个是通过重绘,这样在你移动或者改变窗口大小的时候可以保持程序还是正常是实现绘图模式,另外一个就是通过渲染,由于是一个动态的变化,所以需要时间函数来控制变化情况,分别在主窗口部分绘制太阳,地球和月亮,其中对于地球和月亮需要设置旋转角度和平移,而太阳是静态图形,很好绘制,直接调用绘图函数即可,而且由于旋转变化的原因,超过360度要处理,所以需要设定步长,最后通过主循环和时间来控制动态显示,直到用户关闭。三、实验结果四、源程序#include #include float day = 0; / 地球自转角度float month = 0; / 月亮自转和公转角度float year = 0; / 地球公转角度float sun = 0; / 太阳自转角度/ 设置光源void setLight() float pos4 = 1, 0, 0, 1, -1, 0, 0, 1, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 1, 0, 1,
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1