谷萌计算机图形学实验资料.docx
《谷萌计算机图形学实验资料.docx》由会员分享,可在线阅读,更多相关《谷萌计算机图形学实验资料.docx(16页珍藏版)》请在冰豆网上搜索。
谷萌计算机图形学实验资料
实验报告
题目:
计算机图形学
院(系):
信息与控制工程学院
专业班级:
计算机1202
姓名:
谷萌
学号:
120620218
指导教师:
周方晓
2015年12月12日
实验一熟悉Windows图形开发环境
一、实验目的
1. 熟悉VisualC++6.0的开发环境;
2. 掌握Windows图形输出的方法;
3. 理解设备环境、画笔、画刷的概念,掌握常用的绘制函数。
二、实验原理
原理:
使用Visual C++在Windows下进行图形程序设计
三、实验内容
内容:
编写程序,要求如下:
1. 定义一支红色画笔,绘制一个正方形;
2. 用不同颜色的线条连接互不相临的两个顶点;
3. 用不同颜色的画刷填充用上述方法所形成的图形的每一个区域。
四、实验步骤
使用VisualC++在Windows下进行图形程序设计的基本步骤是:
(1)在绘制之前,创建绘图工具并设置相关的颜色、线型、线宽等属性;
(2)调用相关的绘图函数选择绘图工具并进行绘图;
(3)在绘制之后,恢复原有的绘图工具。
五、实验环境
已安装visual C++6.0的Windows XP计算机一台,u盘
六、实验结果及分析
运行结果如图所示
分析:
代码调试完毕,编译运行,按预期结果输出。
七、实验小结
对我来说这次实验既是一次挑战也是一次全新的学习机会。
当然这也是我第一次编写Windows图形程序,所以在编写过程中发现了许多问题,比如说vc++6.0软件存在问题,导致程序总是出现一些莫名其妙的错误,像无法打开工程,自动关闭等等。
后来,经过询问老师和上网查询,才发现是软件和我的系统有兼容性问题,与一些软件也存在冲突。
后来在网上的建议,我换成Windows xp的虚拟机中运行,此问题得到了解决。
除此之外,程序编写时将工程类型创建错了,导致无法连接成功。
后来经过上网搜索相关内容解决了此问题。
然后在调用一些画图的函数时对函数体了解不多,导致函数调用出错。
实验二创建VC6.0下OpenGL绘图程序的基本框架
一、实验目的
1. 了解使用VC6.0下 OpenGL绘图程序的基本框架
2. 掌握理解简单的OpenGL程序结构;
3. 掌握OpenGL提供的基本图形函数,尤其是生成点、线、面的函数。
二、实验环境
安装有Visual C++ 6.0的windowXp计算机一台,u盘。
三、实验原理内容步骤
新建工程,在工程—设置—链接—L对象库模版中添加OPENGL库,
即opengl32.libglu32.libglaux.lib
如图所示:
在VisualC++中,修改视图类成员函数代码实现OpenGL绘图的过程如下:
①在(文件名.view)视图类中改造PreCreateWindow函数:
将窗口的客户区设置为OpenGL能够支持的风格。
具体添加代码如下:
cs.style|=WS_CLIPCHILDREN|WS_CLIPSIBLINGS;
②在工具栏的视图——类向导中添加并改造OnCreate函数:
定义像素存储格式,并创建一个OpenGL操作所必须的绘图上下文RC(RenderingContext)。
使用一个PIXELFORMATDESCRIPTOR结构来指定像素格式,使用wglCreateContext()函数创建绘图上下文RC。
添加头文件:
#include"GL\glu.h"
#include"GL\gl.h"
#include"GL\glaux.h"
OnCreate函数中具体添加代码如下:
//首先定义像素存储格式
PIXELFORMATDESCRIPTORpfd=
{
sizeof(PIXELFORMATDESCRIPTOR),//pfd的大小
1,//结构的版本号
PFD_DRAW_TO_WINDOW|//支持window
PFD_SUPPORT_OPENGL|//支持OpenGL
PFD_DOUBLEBUFFER,//双缓存
PFD_TYPE_RGBA,//RGBA颜色模式
24,//24位颜色深度缓存
0,0,0,0,0,0,//colorbitsignored
0,//noalphabuffer
0,//shiftbitignored
0,//不使用累积缓存
0,0,0,0,//accumbitsignored
32,//32位z缓冲
0,//不使用模板缓存
0,//noauxiliarybuffer
PFD_MAIN_PLANE,//选择主层面
0,//保留
0,0,0//layermasksignored
};
CClientDCdc(this);
intpixelFormat=ChoosePixelFormat(dc.m_hDC,&pfd);
BOOLsuccess=SetPixelFormat(dc.m_hDC,pixelFormat,&pfd);
//创建绘图上下文RC
HGLRCm_hRC=wglCreateContext(dc.m_hDC);
③在工具栏的视图——类向导中添加并改造OnSize函数:
当视图尺寸变化是,应及时将新的客户区尺寸通知OpenGL,方能够正确在窗口客户区域显示二维场景,通过命令glViewport完成这项工作:
glViewport(0,0,cx,cy);
具体添加代码如下:
if(cy>0&&cx>0)
{
glViewport(0,0,cx,cy);////视口设置成应用程序的视图的大小
glMatrixMode(GL_PROJECTION);//投影矩阵模式
glLoadIdentity();
////if...else...语句是平行投影的实现方式
////参数:
左、右、下、上、近、远
if(cx<=cy)/////原先是3.0左,右,下,上,近,远
glOrtho(-4.0,4.0,-4.0*(GLfloat)cx/(GLfloat)cy,
4.0*(GLfloat)cx/(GLfloat)cy,-10.0,10.0);
else
glOrtho(-4.0,4.0,-4.0*(GLfloat)cy/(GLfloat)cx,
4.0*(GLfloat)cy/(GLfloat)cx,-10.0,10.0);
//else
glFrustum(-2.0,2.0,-2.0*cy/double(cx),2.0*cy/double(cx),2.0,6.0);
/*可以乘一个自定义的投影矩阵实现投影:
doubleProjectMatrix[4][4];
....计算投影矩阵ProjectMatrix
glMultMatrixd(&ProjectMatrix[0][0]);
*/
}
glMatrixMode(GL_MODELVIEW);//以下是模型变换矩阵模式
glTranslatef(0.0,0.0,-4.0);//拉开视点和物体
glRotated(20,0.5,1.0,0.5);
④在工具栏的视图——类向导中添加并改造OnEraseBkgnd函数:
重载视图类的OnEraseBkgnd成员,使之返回TRUE值可以阻止Windows重画窗口背景,因为OpenGL自己会设置窗口背景,这样可以防止窗口频繁刷新(如移动窗口)时产生的闪烁现象。
⑤在工具栏的视图——类向导中添加并改造OnDestroy函数:
在OnDestroy成员中需要释放OnCreate成员中RC所占用的资源,命令wglDeleteContext可以完成这个工作,但在释放RC之前,还需要使用命令wglMakeCurrent()断开RC与设备描述表DC的连接。
具体代码如下:
wglMakeCurrent(NULL,NULL);
wglDeleteContext(m_hRC);
添加成员变量:
⑥改造OnDraw:
根据当前的视点、视距、观看方向等参数,设置合适的OpenGL视景体属性,使用户能够看到预期的场景外观。
添加的代码如下:
wglMakeCurrent(pDC->m_hDC,m_hRC);
DrawScene();//用户自定义函数,用来编写OpenGL绘制语句的
wglMakeCurrent(pDC->m_hDC,NULL);
添加成员函数:
在DrawScene()函数中编写具体的绘图程序。
首先需要设置视点、视距和观看方向等场景参数,然后绘制图元。
四、 实验结果
编译并运行该程序
1.该程序的作用是在一个黑色的窗口中央画一个矩形、三角形和三个点。
图2-1是示范程序的结果,添加代码,在原有结果基础上添加三条直线组成新的三角形(如图2-2所示),将增加的代码写在实验报告纸上。
2.使用Visual Studio C++编译已有项目工程,并编写代码生成以下图形,如图2-3所示。
3.在此基础上,修改各顶点颜色,使得每个顶点颜色不一样,多边形内部颜色渐变,如图2-4所示(该程序需使用双缓存区)。
3、在此基础上,修改各顶点颜色,使得每个顶点颜色不一样,多边形内部颜色渐变,如图2-4所示(该程序需使用双缓存区)。
五、实验小结
通过本次实验,使我对VC6.0下 OpenGL绘图程序的基本框架有了许多的理解,同时也掌握了一些简单的OpenGL程序结构,对OpenGL提供的基本图形函数,有了许多了解,其中尤其是生成点、线、面的函数的使用,有了非常多的理解。
实验三用OpenGL绘制基本图元(直线、多边形等)
一、实验目的
1. 学会使用OpenGL绘制基本图元;
2. 利用OpenGL实现实线,虚线,点划线的绘制,及kock曲线。
二、实验原理
该实验是基于实验二基础上,步骤省略。
添加成员函数intDrawGLScene(GLvoid):
实验代码如下:
intDrawGLScene(GLvoid)//Here'sWhereWeDoAllTheDrawing
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);//ClearScreenAndDepthBuffer
glLoadIdentity();//ResetTheCurrentModelviewMatrix
//Drawline
glBegin(GL_LINES);
glColor3f(1.0,0.0,0.0);//设置颜色为红色
glVertex2f(0,0);
glVertex2f(1,1);
glColor3f(0.0,1.0,0.0);//设置颜色为绿色
glVertex2f(0.2,0);
glVertex2f(1.2,1);
glEnd();
glTranslatef(-1.5f,0.0f,-6.0f);//MoveLeft1.5UnitsAndIntoTheScreen6.0
////DrawingTriangles
glBegin(GL_TRIANGLES);//DrawingUsingTriangles
glVertex3f(0.0f,1.0f,0.0f);//Top
glVertex3f(-1.0f,-1.0f,0.0f);//BottomLeft
glVertex3f(1.0f,-1.0f,0.0f);//BottomRight
glEnd();//FinishedDrawingTheTriangle
glTranslatef(3.0f,0.0f,0.0f);//MoveRight3Units
////DrawQuad
glBegin(GL_QUADS);//DrawAQuad
glVertex3f(-1.0f,1.0f,0.0f);//TopLeft
glVertex3f(1.0f,1.0f,0.0f);//TopRight
glVertex3f(1.0f,-1.0f,0.0f);//BottomRight
glVertex3f(-1.0f,-1.0f,0.0f);//BottomLeft
glEnd();//DoneDrawingTheQuad
returnTRUE;//KeepGoing
}
三、实验内容
1. 用OpenGL程序绘制实现,虚线和点划线
2. 用OpenGL程序,分别以直线和正三角形为初始生成员,实现迭代次数在6次以内的kock曲线,要求用键盘交互控制迭代次数。
四、实验环境
安装有Visual C++6.0的windowXp计算机一台,u盘
五、实验步骤
1)相关算法及原理描述
①直线的绘制
在OpenGL中绘制直线通过指定直线段的端点来实现,用glVertex函数指定直线段端点的坐标位置,用glBegin/glEnd函数对包含一系列的点坐标,并利用符号常量解释这些点构成直线的方式。
②虚线的绘制
绘制虚线需要先调用函数过了Enable(GL_LINE_STIPPLE);打开划线模式。
然后,函数glLineStipple将建立用于划线的模式 glLineStipple(Glint factor, GLushort pattern);
③ Kock曲线
Kock曲线的初始生成员是一条直线,生成规则是将直线段分为三等分,首尾两段保持不变,中间用两段等长且互成60°角的直线段代替。
这样,直线段被分成四段,每段长度都只有原来的1/3。
Kock曲线的分形维数为D=ln4/ln3≈1.26186 假设原直线的首尾点是P0(x0,y0),P1(x1,y1),则新的四段直线段的五个端点坐标分别为
(x0 , y0) (x0+(x1-x0)/3 , y0+(y1-y0)/3) ((x1+x0)/2±(y0-y1)√3/6 , (y1+y0)/2±(x1-x0)√3/6) (x0+2(x1-x0)/3 , y0+2(y1-y0)/3) (x1 , y1)
其中,第三个点坐标公式中的正负号表示中间两条心直线段处于元直线段的哪一侧。
根据这一规则迭代六次。
六、实验结果及分析
程序调试、测试与运行结果分析:
1 直线的绘制结果
2虚线的绘制结果
3Kock曲线绘制结果
六、实验小结
通过本次实验使我学会使用OpenGL绘制基本图元,并利用OpenGL实现实线,虚线,点划线的绘制,及对kock曲线,对直线、虚线、Kock曲线的绘制有了一定的了解与掌握。
通过实验,对图形学中所用算法也有了更深的认识,并且通过从八分圆构造完整圆的过程,学会了图形学算法设计的一种思想
实验四用OpenGL生成NURBS曲线
一、实验目的
(1)理解Bézier曲线和B样条曲线的定义、性质及绘制算法;
(2)理解OpenGL中窗口坐标与世界坐标的映射关系;
(3)掌握OpenGL的Bézier曲线和NURBS曲线的绘制方法。
二、实验原理,内容及步骤
openGL中,GLU函数库提供了一个NURBS接口。
用户需要提供的数据包括控制点、节点等数据,控制点描述曲线的大致形状,节点控制B样条函数的形状。
绘制一条NURBS曲线的步骤:
(1)提供控制点序列和节点序列;
(2)创建一个NURBS对象,设置NURBS对象属性;
(3)绘制曲线;
创建一个NURBS对象,用如下两条语句:
GLUnurbsObj*theNurbs;
theNurbs=gluNewNurbsRender();
创建对象后,用如下函数设置NURBS对象属性:
voidgluNurbsProperty(GLUnurbsObj*nobj,GLenumproperty,Glfloatvalue);
曲线的绘制是在gluBeginCurve()/gluEndCurve()函数对中完成。
绘制曲线的函数为:
voidgluNurbsCurve(GLUnurbsObj*nobj,GLintnknots,GLfloat*knot,
GLintstride,GLfloat*ctlarray,GLintorder,GLenumtype);
具体参数含义在下面程序实现中解释。
添加成员函数DrawNurbsCurve():
voidCView:
:
DrawNurbsCurve()
{
GLfloatcontrolPoints[7][3]={{-1.5f,-0.5f,0.0f},{-1.0f,1.0f,0.0f},
{-0.5f,-0.5f,0.0f},{0.0f,-2.0f,0.0f},
{0.5f,-0.5f,0.0f},{1.0f,1.0f,0.0f},{1.5f,-0.5f,0.0f}
};//给定控制点
GLfloatknots[14]={0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,
1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f};//节点
glColor3f(0.0f,0.0f,1.0f);
GLUnurbsObj*theNurb;//创建NURBS对象
theNurb=gluNewNurbsRenderer();
gluNurbsProperty(theNurb,GLU_SAMPLING_TOLERANCE,10.0);//属性
//GLU_SAMPLING_TOLERANCE表示边缘最大像素长度
glNewList(1,GL_COMPILE);
gluBeginCurve(theNurb);
gluNurbsCurve(theNurb,/*NURBS曲线对象*/
14,/*参数区间节点数目=控制点数+NURBS曲线阶数*/
knots,/*节点*/
3,/*曲线控制点之间的偏移量*/
(float*)controlPoints,/*控制点*/
7,/*曲线阶数*/
GL_MAP1_VERTEX_3);/*曲线类型*/
gluEndCurve(theNurb);
glEndList();
glCallList
(1);
}
三、实验结果
四、实验小结
通过本次实验,虽然实验过程没有完整编写OpenGL程序代码,但是在老师给出的程序框架中,通过添加函数及修改相应的函数参数,基本完成了实验内容,并加深理解了OpenGL编程思想及计算机中图形绘制的流水线。