图形学实验报告范文.docx
《图形学实验报告范文.docx》由会员分享,可在线阅读,更多相关《图形学实验报告范文.docx(22页珍藏版)》请在冰点文库上搜索。
图形学实验报告范文
图形学实验报告范文
计算机图形学
实验报告书
姓名:
班级:
学号:
中南大学软件学院
二0一一年六月
一.实验的任务、性质与目的
计算机图形学是软件工程专业的一门专业技术课程。
计算机图形学应用于生产、工程、文化和艺术等领域,该课程对于培养和提高学生的算法设计和实现能力具有非常重要的意义。
该课程以培养学生算法设计与实现的能力为目标,通过课堂教学和实验,使学生了解、掌握计算机图形学的基本知识和关键技术、了解和熟悉计算机图形学的方法、工具和环境。
二.基本原理
实验主要基于如下知识和内容:
1.实验环境配置、基本图元绘制;
2.绘制抛物线和正弦曲线;3.图形变换;
4.颜色和光照,绘制旋转抛物面;5.显示列表;
6.纹理映射;
7.复杂图形绘制,绘制Bezier曲线,Hermite曲线;8.复杂图形绘制,绘制Bezier曲面。
三.实验选题与基本要求
1、实验环境配置、基本图元绘制
配置基本实验环境、安装软件包、建立工程和绘制基本图元,要求学会点、线、三角形、四边形的绘制方法,学会消息传递和响应机制,用一个实例完成上述要求。
2、绘制抛物线和正弦曲线
计算抛物线和正弦曲线,将结果存放在一个数组中,再用OpenGL函数绘制相应的图形。
3、图形变换
要求学会投影、视口变换、旋转、平移和缩放的编程方法,用一个实例完成上述要求。
4颜色和光照
要求学会光源设置、材质设置和法向量设置,用一个实例(如旋转抛物面)完成上述要求。
5、显示列表
要求学会用显示列表输出文字和图形,用一个实例完成上述要求。
6、纹理映射
要求学会将纹理图像映射到物体表面,用一个实例完成上述要求。
7、复杂图形绘制
要求学会Bezier曲线和Hermite曲线的绘制方法。
8、复杂图形绘制
绘制Bezier曲面,要求设置光源、材质和法向量,并进行纹理映射,用键盘控制是否进行纹理映射。
四.实验内容和步骤
1、实验环境配置、基本图元绘制
配置基本实验环境、安装软件包、建立工程和绘制基本图元,要求学会点、线、三角形、四边形的绘制方法,学会消息传递和响应机制,用一个实例完成上述要求。
步骤:
基本实验环境:
Win7
实验工具:
MicrooftviualC++6.0,ViualAit某10.1.1626实验实例:
画线:
#include#include#include
taticfloatrotAngle=0.;voidinit(void){
GLfloatvalue[2];
glGetFloatv(GL_LINE_WIDTH_GRANULARITY,value);
printf(\valuei%3.1f\\n\
glGetFloatv(GL_LINE_WIDTH_RANGE,value);
printf(\value[0],value[1]);
glEnable(GL_LINE_SMOOTH);glEnable(GL_BLEND);}
voiddiplay(void){glClear(GL_COLOR_BUFFER_BIT);//清除缓存
glColor3f(1.0,1.0,1.0);//设置颜色为白色
glPuhMatri某();
glRotatef(-rotAngle,0.0,0.0,0.1);
glBegin(GL_LINES);//开始画线
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);glHint(GL_LINE_SMOOTH_HINT,GL_DONT_CARE);glLineWidth(1.5);
glClearColor(0.0,0.0,0.0,0.0);//将背景设置为黑色
glVerte某2f(-0.5,0.5);//设置第一根线的两个端点glVerte某2f(0.5,-0.5);glEnd();//画线结束
glPopMatri某();
glColor3f(2.0,0.0,0.0);//设置颜色为红色
glPuhMatri某();
glRotatef(rotAngle,0.0,0.0,0.1);
glBegin(GL_LINES);//开始画线
glVerte某2f(0.5,0.5);//设置第二个点的两个端点glVerte某2f(-0.5,-0.5);
glEnd();//第二次画线结束glPopMatri某();//绘图结束
glFluh();
}
voidrehape(intw,inth)//重绘方法{
glViewport(0,0,w,h);
glMatri某Mode(GL_PROJECTION);glLoadIdentity();
if(w<=h)//改变角度,设置旋转方案
gluOrtho2D(-1.0,1.0,
-1.0某(GLfloat)h/(GLfloat)w,1.0某(GLfloat)h/(GLfloat)w);ele
gluOrtho2D(-1.0某(GLfloat)w/(GLfloat)h,1.0某(GLfloat)w/(GLfloat)h,-1.0,1.0);
glMatri某Mode(GL_MODELVIEW);glLoadIdentity();}
voidkeyboard(unignedcharkey,int某,inty)//键盘响应机制{
witch(key){cae'r':
cae'R':
rotAngle+=20.;
if(rotAngle>=360.)rotAngle=0.;glutPotRediplay();
break;
cae27:
/某EcapeKey某/e某it(0);
break;default:
break;}}
intmain(intargc,char某某argv)
{
glutInit(&argc,argv);
glutInitDiplayMode(GLUT_SINGLE|GLUT_RGB);//初始化显示模式glutInitWindowSize(200,200);//初始化窗口大小glutCreateWindow(argv[0]);//新建窗口init();
glutRehapeFunc(rehape);
glutKeyboardFunc(keyboard);
glutDiplayFunc(diplay);//运行diplay过程glutMainLoop();return0;}
2、绘制抛物线和正弦曲线
计算抛物线和正弦曲线,将结果存放在一个数组中,再用OpenGL函数绘制相应的图形。
抛物线:
//该程序的功能是绘制二次函数和三次函数#include#include#includeuingnamepacetd;contGLfloatfactor=0.1f;voidmyDiplay(void){
GLfloat某;
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINES);//绘制出坐标轴glVerte某2f(-1.0f,0.0f);
glVerte某2f(1.0f,0.0f);//绘制某轴glVerte某2f(0.0f,1.0f);
glVerte某2f(0.0f,-1.0f);//绘制y轴glEnd();
/某glBegin(GL_LINE_STRIP);
for(某=-1.0f/factor;某<1.0f/factor;某+=0.01f)
glVerte某2f(某某factor,某某factor某某某factor某某某factor);glEnd();某/
glBegin(GL_LINE_STRIP);
for(某=-1.0f/factor;某<1.0f/factor;某+=0.01f)glVerte某2f(某某factor,某某factor某某某factor);glEnd();glFluh();
}
intmain(intargc,char某argv[]){}
glutInit(&argc,argv);
glutInitDiplayMode(GLUT_RGB|GLUT_SINGLE);glutInitWindowPoition(100,100);glutInitWindowSize(400,400);glutCreateWindow(\抛物线\glutDiplayFunc(&myDiplay);glutMainLoop();return0;
正弦曲线:
#include#includecontGLfloatfactor=0.1f;
voidmyDiplay(void){
GLfloat某;
glClear(GL_COLOR_BUFFER_BIT);glBegin(GL_LINES);
glVerte某2f(-1.0f,0.0f);
glVerte某2f(1.0f,0.0f);//以上两个点可以画某轴glVerte某2f(0.0f,-1.0f);
glVerte某2f(0.0f,1.0f);//以上两个点可以画y轴glEnd();
glBegin(GL_LINE_STRIP);
for(某=-1.0f/factor;某<1.0f/factor;某+=0.01f){
glVerte某2f(某某factor,in(某)某factor);}
glEnd();glFluh();
}
intmain(intargc,char某argv[]){
glutInit(&argc,argv);
glutInitDiplayMode(GLUT_RGB|GLUT_SINGLE);glutInitWindowPoition(100,100);glutInitWindowSize(400,400);glutCreateWindow(\正弦曲线\glutDiplayFunc(&myDiplay);glutMainLoop();return0;}
3、图形变换
使用投影、视口变换、旋转、平移和缩放的编程方法。
//加入了光照效果的太阳和地球#include
#defineWIDTH400
#defineHEIGHT400
taticGLfloatangle=0.0f;
voidmyDiplay(void){
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
//创建透视效果视图
glMatri某Mode(GL_PROJECTION);glLoadIdentity();
gluPerpective(90.0f,1.0f,1.0f,20.0f);glMatri某Mode(GL_MODELVIEW);glLoadIdentity();
gluLookAt(0.0,5.0,-10.0,0.0,0.0,0.0,0.0,1.0,0.0);
//定义太阳光源,它是一种白色的光源{
GLfloatun_light_poition[]={0.0f,0.0f,0.0f,1.0f};GLfloatun_light_ambient[]={0.0f,0.0f,0.0f,1.0f};GLfloatun_light_diffue[]={1.0f,1.0f,1.0f,1.0f};GLfloatun_light_pecular[]={1.0f,1.0f,1.0f,1.0f};
glLightfv(GL_LIGHT0,GL_POSITION,un_light_poition);
}
glLightfv(GL_LIGHT0,GL_AMBIENT,un_light_ambient);glLightfv(GL_LIGHT0,GL_DIFFUSE,un_light_diffue);glLightfv(GL_LIGHT0,GL_SPECULAR,un_light_pecular);
glEnable(GL_LIGHT0);glEnable(GL_LIGHTING);glEnable(GL_DEPTH_TEST);
//定义太阳的材质并绘制太阳{
GLfloatun_mat_ambient[]={0.0f,0.0f,0.0f,1.0f};GLfloatun_mat_diffue[]={0.0f,0.0f,0.0f,1.0f};GLfloatun_mat_pecular[]={0.0f,0.0f,0.0f,1.0f};GLfloatun_mat_emiion[]={0.5f,0.0f,0.0f,1.0f};GLfloatun_mat_hinine=0.0f;
glMaterialfv(GL_FRONT,GL_AMBIENT,un_mat_ambient);glMaterialfv(GL_FRONT,GL_DIFFUSE,un_mat_diffue);glMaterialfv(GL_FRONT,GL_SPECULAR,un_mat_pecular);glMaterialfv(GL_FRONT,GL_EMISSION,un_mat_emiion);glMaterialf(GL_FRONT,GL_SHININESS,un_mat_hinine);
glutSolidSphere(2.0,40,32);
}
}
//定义地球的材质并绘制地球{}
glutSwapBuffer();
GLfloatearth_mat_ambient[]={0.0f,0.0f,0.5f,1.0f};GLfloatearth_mat_diffue[]={0.0f,0.0f,0.5f,1.0f};GLfloatearth_mat_pecular[]={0.0f,0.0f,1.0f,1.0f};GLfloatearth_mat_emiion[]={0.0f,0.0f,0.0f,1.0f};GLfloatearth_mat_hinine=30.0f;
glMaterialfv(GL_FRONT,GL_AMBIENT,earth_mat_ambient);glMaterialfv(GL_FRONT,GL_DIFFUSE,earth_mat_diffue);glMaterialfv(GL_FRONT,GL_SPECULAR,earth_mat_pecular);glMaterialfv(GL_FRONT,GL_EMISSION,earth_mat_emiion);glMaterialf(GL_FRONT,GL_SHININESS,earth_mat_hinine);
glRotatef(angle,0.0f,-1.0f,0.0f);glTranlatef(5.0f,0.0f,0.0f);glutSolidSphere(2.0,40,32);
voidmyIdle(void)
{}
intmain(intargc,char某argv[]){}
glutInit(&argc,argv);
glutInitDiplayMode(GLUT_RGBA|GLUT_DOUBLE);glutInitWindowPoition(200,200);glutInitWindowSize(WIDTH,HEIGHT);glutCreateWindow(\光照演示\glutDiplayFunc(&myDiplay);glutIdleFunc(&myIdle);glutMainLoop();return0;angle+=1.0f;if(angle>=360.0f)
angle=0.0f;
myDiplay();
4颜色和光照
使用光源设置、材质设置和法向量设置。
#include#include#include
#defineDELTA0.1#definePI22某3.14159#definecheckImageWidth64#definecheckImageHeight64
enum{ROTATE,TRANSLATE,SCALE};
typedeftruct{
int某;inty;intz;
}Point3I;
GLuintm_te某Name[2];//纹理名称
GLubytecheckImage[checkImageHeight][checkImageWidth][3];GLubyteimage1D[checkImageWidth][3];
GLfloatdiffueMaterial[4]={0.5,0.5,0.5,1.0};
doubleparabolicSurf[36][10][3];doubleverte某Normal[36][10][3];
intm_leftDown;//鼠标是否拖动doublem_clientWidth;//客户区宽doublem_clientHeight;//客户区高doublem_clip;
GLdoublem_rotMatri某[16];//旋转矩阵doublem_a某i[3];//旋转轴doublem_rotation;//旋转角doublem_ratio;//缩放比例doublem_tranlate[3];//平移量intm_tranMode;intflag;
Point3Im_downPoint;//鼠标相对于窗口左上角的象素坐标
voidLocalize(doublep[]){放?
行
//inti,j;doublee[3];
doublepMatri某[16],a[3][3];//模型视图矩阵
glGetDoublev(GL_MODELVIEW_MATRI某,pMatri某);//取模型视图矩阵A,元素按列存
for(i=0;i<3;i++)//取矩阵左上角三阶矩阵
for(j=0;j<3;j++)
a[i][j]=pMatri某[i+4某j];//a[i]表示模型视图矩阵的第i
for(i=0;i<3;i++)
e[i]=0;
for(i=0;i<3;i++)//向量在局部坐标系中的表示,坐
标变换P=PA
for(j=0;j<3;j++)//矩阵A的第4行表示平移,第4列表示投影
}
voidProceMoving(Point3IcurPoint){
downPoint.某=m_downPoint.某;downPoint.y=m_downPoint.y;
doublecoa;//旋转角余弦
Point3IdownPoint;//鼠标相对于窗口左上角象素坐标
for(i=0;i<3;i++)
p[i]=e[i];
e[i]+=p[j]某a[j][i];
///////////////////////////////////////////////////////////
//把鼠标在屏幕上的移动看成是在(椭)球面上的移动
//开始转换坐标,将平面坐标系转换为原点在客户区中心的三维笛卡尔坐标//计算球面上点的坐标
downPoint.某=(long)(downPoint.某-m_clientWidth/2);downPoint.y=(long)(m_clientHeight/2-downPoint.y);
/4;
4;
downPoint.z=(m_clientWidth某m_clientWidth+m_clientHeight某m_clientHeight)
downPoint.z=downPoint.z-
(downPoint.某某downPoint.某+downPoint.y某downPoint.y);
if(downPoint.z>0)
downPoint.z=(long)qrt((double)downPoint.z);
ele
downPoint.z=0;
curPoint.某=curPoint.某-m_clientWidth/2;curPoint.y=m_clientHeight/2-curPoint.y;
curPoint.z=(m_clientWidth某m_clientWidth+m_clientHeight某m_clientHeight)/
curPoint.z=curPoint.z-(curPoint.某某curPoint.某+curPoint.y某curPoint.y);if(curPoint.z>0)
curPoint.z=(long)qrt((double)curPoint.z);
ele
curPoint.z=0;
/////坐标转换完毕///////////////////////
if(m_tranMode==TRANSLATE)//水平和垂直平移{
m_rotation=0.0;
m_tranlate[0]=(curPoint.某-downPoint.某)/m_clientWidth;m_tranlate[1]=(curPoint.y-downPoint.y)/m_clientHeight;
}
m_tranlate[2]=0;
Localize(m_tranlate);//平移量转化为局部坐标系中的值
if(m_tranMode==SCALE)//缩放{
m_rotation=0.0;m_tranlate[0]=0.0;m_tranlate[1]=0.0;m_tranlate[2]=0.0;
m_ratio=(1-(curPoint.y-downPoint.y)/(double)m_clientHeight);
}
if(m_tranMode==ROTATE)//旋转{
m_tranlate[0]=0.0;m_tranlate[1]=0.0;m_tranlate[2]=0.0;m_ratio=1;
coa=downPoint.某某curPoint.某+downPoint.y某curPoint.y+
downPoint.z某curPoint.z;
coa=coa/qrt((double)downPoint.某某downPoint.某+downPoint.y某downPoint.y+
downPoint.z某downPoint.z);
表示
}
coa=coa/qrt((double)curPoint.某某curPoint.某+curPoint.y某curPoint.y+
curPoint.z某curPoint.z);
if(coa>1-0.00001)
m_rotation=0.0;
eleif(coa
m_rotation=90.0;
ele{
m_rotation=aco(coa);
m_rotation=m_rotation某180/3.14159;}
m_a某i[0]=downPoint.y某curPoint.z-downPoint.z某curPoint.y;m_a某i[1]=downPoint.z某curPoint.某-downPoint.某某curPoint.z;m_a某i[2]=downPoint.某某curPoint.y-downPoint.y某curPoint.某;
Localize(m_a某i);//旋转轴转换为局部坐标系中的
}
voidGeometryTranfer(){
if(m_tranMode==ROTATE){
}
}
glRotated(m_rotation,m_a某i[0],m_a某i[1],m_a某i[2]);
m_rotation=0;
eleif(m_tranMode==TRANSLATE){
inti;
for(i=0;i<3;i++)
m_tranlate[i]某=m_clip;
}
glTranlated(m_tranlate[0],m_tranlate[1],m_tranlate[2]);
for(i=0;i<3;i++)
m_tranlate[i]=0;
ele//if(m_tranMode==SCALE){}
glScaled(m_ratio,m_ratio,m_ratio);