实验六 3D编程及Bezier曲线绘制.docx
- 文档编号:10898820
- 上传时间:2023-05-28
- 格式:DOCX
- 页数:17
- 大小:33.62KB
实验六 3D编程及Bezier曲线绘制.docx
《实验六 3D编程及Bezier曲线绘制.docx》由会员分享,可在线阅读,更多相关《实验六 3D编程及Bezier曲线绘制.docx(17页珍藏版)》请在冰点文库上搜索。
实验六3D编程及Bezier曲线绘制
实验七3D编程及Bezier曲线曲面绘制
一、实验目的
1.3D编程:
熟悉视点观察函数的设置和使用;熟悉投影变换函数的设置和使用;熟悉基本3D图元的绘制
2.了解OpenGL绘制Bezier曲线的方法
二、实验环境
硬件要求:
PC机,主流配置,最好为独立显卡,显存512M以上。
软件环境:
操作系统:
WindowsXP。
语言开发工具:
VC6.0。
三、实验要求:
按照实验内容做实验,保留所作步骤效果截图或演示程序,当场检查,现场计分
四、实验内容
1.3D编程
3DCube.cpp为一静止3D立方体,3DCube2.cpp为正交投影下的旋转3D立方体,按下鼠标可实现不同方向的旋转。
分析3D编程代码与程序结构。
图7-1静止立方体效果图图7-2旋转立方体效果图图7-3旋转茶壶和圆环效果图
1.让静止的立方体绕Z轴不停旋转
2.修改视点,目标点不变,观看显示效果
3.修改目标点,视点不动,观看显示效果
4.视点与目标点同时修改,观看显示效果
5.视点与目标点不变,修改观察体大小,观看显示效果
6.将正交投影观察体改为透视投影观察体,并设置其大小,观察显示效果
7.将立方体替换为茶壶,观看显示效果.
选做
2.Bezier曲线绘制
BezierCurve.cpp为绘制bezier曲线的源程序,仔细研读源程序,并作如下修改
1).改变控制点,观察曲线和曲面形状的变化,控制点起什么作用?
2).改写bezier.cpp,增加控制点数目,修改控制点位置,使之成为空间封闭曲线,写出修改的关键代码及注释(TIPS:
OpenGLBezier曲线绘制方法最多只能有8个控制点)
3).根据bezier曲线的性质,改写程序,使之成为两段曲线光滑连接。
每段曲线用不同颜色表示,并画出控制点。
图7-2·Bezier曲线绘制效果
五、函数参考
(一)3D编程
1.视点设置函数
voidgluLookAt(GLdoubleeyex,GLdoubleeyey,GLdoubleeyez,GLdoubleatx,GLdoubleaty,GLdoubleatz,GLdoubleupx,GLdoubleupy,GLdoubleupz)
给出矩阵作用于当前矩阵,定义相机位置和方向
视点:
eyex,eyey,eyez
目标点:
atx,aty,atz
相机向上方向:
upx,upy,upz
如果不引用该函数,则eyex=0,eyey=0,eyez=0,atx=0,aty=0,atz=-1,Upx=0,upy=1,upz=0此函数放在display函数中调用
参考坐标系:
世界坐标系
2.正交投影变换设置函数
.voidglOrtho(GLdoubleleft,GLdoubleright,GLdoublebottom,GLdoubletop,GLdoublenear,GLdoublefar),建立正交投影矩阵,定义一个正平行观察体。
距离从相机位置处测量。
right>left,top>bottom,far>near
OpenGL中不提供对观察平面的选择功能。
近裁减平面永远和观察平面重合。
如果OpenGL不提供投影函数,默认调用为:
glOrtho(-1.0,1.0,-1.0,1.0,-1.0,1.0)
3.透视投影变换设置函数
voidgluPerspective(GLdoublefov,GLdoubleaspect,GLdoublenear,GLdoublefar),定义一个透视矩阵作用于当前矩阵
fov-近裁剪平面与远裁剪平面的连线与视点的角度,也称视场角(field-of-viewangle)
aspect-投影平面的宽与高之比
near,far-近裁剪平面和远裁剪平面离相机(视点)的距离
4.三维基本图形绘制函数
1)立方体绘制函数
voidglutWireCube(GLdoublesize)//线框模式
voidglutSolidCube(GLdoublesize)//实体模式
功能:
绘制一个边长为size的线框的或实心立方体,立方体的中心位于原点
2)小球绘制函数
.voidglutWireSphere(GLdoubleRadius,Glintslices,Glintstacks)
voidglutSolidSphere(GLdoubleRadius,Glintslices,Glintstacks);
功能:
绘制一个半径为Radius的线框的的或实心小球,小球的中心点位于原点,slices:
为小球的经线数目,stacks为小球的纬线数目
3)茶壶绘制函数
voidglutWireTeapot(GLdoublesize);
voidglutSolidTeapot(GLdoublesize);
功能:
绘制一个半径为size的线框的或实心茶壶,茶壶的中心位于原点
参数说明:
参数size为茶壶的近似半径,以size为半径的球体可完全包容这个茶壶。
4)圆环绘制函数
.voidglutWireTorus(GLdoubleinnerRadius,GLdoubleouterRadius,Glintslices,Glintstacks);
voidglutWireTorus(GLdoubleinnerRadius,GLdoubleouterRadius,Glintslices,Glintstacks);
功能:
绘制一个半径为size的线框的的或实心圆环体,圆环体的中心位于原点,圆环的内径和外径由参数innerRadius,outerRadius指定
参数说明:
innerRadius:
圆环体的内径
outerRadius:
圆环体的外径
slices:
圆环体的经线数目
stacks:
圆环体的纬线数目
(二)Bezier曲线绘制
1)Bezier曲线绘制步骤:
1.DefiningBeziercurve
voidglMap1{fd}(GLenumtarget,TYPEu1,TYPEu2,GLintstride,GLintorder,constTYPE*points);
●target:
指定控制点所描述的内容
●u1,u2:
曲线的参数范围(t),一般u1=0,u2=1;
●stride:
控制点之间的浮点数或双精度的个数
●order:
次数+1,即控制点的数目
●points:
指向控制点的指针
2.EnablingBeziercurveglEnable(GL_MAP1_VERTEX_3);
3.Calculatingdatapoints
4.Linkinganddrawing
⏹求出Bezier曲线上的详细点
voidglEvalCoord1{fd}(TYPEu)
voidglEvalCoord1{fd}v(TYPE*u)
⏹画出Bezier曲线
glBegin(GL_LINE_STRIP);
for(i=0;i<=100;i++)
glEvalCoord1f((GLfloat)i/100.0);
glEnd();
或
⏹voidglMapGrid{f,d}(GLintn,TYPEu1,TYPEu2);
⏹voidglEvalMesh1(GLenummode,GLintp1,GLintp2);
☐Mode的取值可以是GL_POINT或GL_LINE
⏹相当于glBegin(GL_LINE_STRIP);
for(i=p1;i<=p2;i++)
glEvalCoord1f(u1+i*(u2-u1)/n);
glEnd();
六、附属程序
(一)3D编程
1.3DCube.cpp静止立方体程序
#include
voiddisplay()
{glClear(GL_COLOR_BUFFER_BIT);//清屏
glMatrixMode(GL_MODELVIEW);//矩阵模式设置
glLoadIdentity();//清空矩阵堆栈
gluLookAt(1.4,1.0,0.8,0.0,0.0,0.0,0.0,1.0,0.0);//设置视点
//gluLookAt(1,1.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0);
glColor3f(1,0,0);
//glutWireCube(0.5);
glutSolidCube(0.5);//绘制立方体,立方体中心在坐标原点
glColor3f(0,0,1);
glutWireCube(0.5);//绘制线框立方体,体现边框效果
glutSwapBuffers();
}
voidreshape(intw,inth)
{glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1,1,-1,1,0.5,2.5);//定义三维观察体
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
voidinit()
{glClearColor(0.0,0.0,0.0,0.0);
glLineWidth(3);
//glColor3f(1.0,1.0,1.0);
}
intmain(intargc,char**argv)
{glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
glutInitWindowSize(800,800);
glutInitWindowPosition(0,0);
glutCreateWindow("cube");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
init();
glutMainLoop();
}
2.3DCube2.exe旋转立方体参考程序
#include"math.h"
#include
intflag=0;
//GLfloatvertices[][3]={{-1.0,-1.0,1.0},{-1.0,1.0,1.0},{1.0,1.0,1.0},{1.0,-1.0,1.0},{-1.0,-1.0,-1.0},
//{-1.0,1.0,-1.0},{1.0,1.0,-1.0},{1.0,-1.0,-1.0}};
GLfloatvertices[][3]={{-1.0,-1.0,-1.0},{1.0,-1.0,-1.0},{1.0,1.0,-1.0},{-1.0,1.0,-1.0},{-1.0,-1.0,1.0},
{1.0,-1.0,1.0},{1.0,1.0,1.0},{-1.0,1.0,1.0}};
GLfloatcolors[][3]={{1.0,0.0,0.0},{0.0,1.0,1.0},{1.0,1.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0},
{1.0,0.0,1.0},{0.0,1.0,1.0},{1.0,1.0,1.0}};
voidinit()
{
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
glEnable(GL_DEPTH_TEST);
glLineWidth(3);
}
voidpolygon(inta,intb,intc,intd)
{
/*drawapolygonvialistofvertices*/
if(flag==0)
{
glBegin(GL_POLYGON);
glColor3fv(colors[a]);
glVertex3fv(vertices[a]);
glColor3fv(colors[b]);
glVertex3fv(vertices[b]);
glColor3fv(colors[c]);
glVertex3fv(vertices[c]);
glColor3fv(colors[d]);
glVertex3fv(vertices[d]);
glEnd();
}
else
{
glColor3f(0,0,0);
glBegin(GL_POLYGON);
glVertex3fv(vertices[a]);
glVertex3fv(vertices[b]);
glVertex3fv(vertices[c]);
glVertex3fv(vertices[d]);
glEnd();
}
}
voidcolorcube(void)
{
/*mapverticestofaces*/
polygon(0,3,2,1);
polygon(2,3,7,6);
polygon(0,4,7,3);
polygon(1,2,6,5);
polygon(4,5,6,7);
polygon(0,1,5,4);
}
staticGLfloattheta[]={0.0,0.0,0.0};
staticGLintaxis=2;
voiddisplay()
{
//glClear(GL_COLOR_BUFFER_BIT);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(3,3,3,0,0,0,0,1,0);
glRotatef(theta[0],1.0,0.0,0.0);
glRotatef(theta[1],0.0,1.0,0.0);
glRotatef(theta[2],0.0,0.0,1.0);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
flag=0;
colorcube();//绘制彩色立方体
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
flag=1;
colorcube();//绘制彩色立方体
glutSwapBuffers();
}
voidspinCube()
{
theta[axis]+=0.01;
if(theta[axis]>360.0)theta[axis]-=360.0;
glutPostRedisplay();
}
voidmouse(intbtn,intstate,intx,inty)
{
if(btn==GLUT_LEFT_BUTTON&&state==GLUT_DOWN)axis=0;
if(btn==GLUT_MIDDLE_BUTTON&&state==GLUT_DOWN)axis=1;
if(btn==GLUT_RIGHT_BUTTON&&state==GLUT_DOWN)axis=2;
}
voidreshape(intw,inth)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//定义正交投影观察体
if(w<=h)
glOrtho(-2.0,2.0,-2.0*(GLfloat)h/(GLfloat)w,2.0*(GLfloat)h/(GLfloat)w,1.0,20.0);
else
glOrtho(-2.0*(GLfloat)w/(GLfloat)h,2.0*(GLfloat)w/(GLfloat)h,-2.0,2.0,1.0,20.0);
//gluPerspective(120,w/h,1,60);//定义透视投影投影观察体
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
voidmain(intargc,char**argv)
{
glutInit(&argc,argv);
//glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DETH);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
glutInitWindowSize(800,800);
glutCreateWindow("colorcube");
init();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutIdleFunc(spinCube);
glutMouseFunc(mouse);
glutMainLoop();
}
(二)Bezier曲线绘制
bezierCurve.cpp//Bezier曲线绘制程序
#include
//Thenumberofcontrolpointsforthiscurve
GLintnNumPoints=4;
//controlpointgroup1
GLfloatctrlPoints[4][3]={{-4.0f,0.0f,0.0f},//EndPoint
{-6.0f,4.0f,0.0f},//ControlPoint
{6.0f,-4.0f,0.0f},//ControlPoint
{4.0f,0.0f,0.0f}};//EndPoint
voidChangeSize(intw,inth);
voidDrawPoints(void);
voidRenderScene(void);
voidSetupRC();
intmain(intargc,char**argv)
{glutInit(&argc,argv);//初始化GLUT库;
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);//设置显示模式;(缓冲,颜色类型)
glutInitWindowSize(500,500);
glutInitWindowPosition(1024/2-250,768/2-250);
glutCreateWindow("BezierCurve");//创建窗口,标题为“Rotating3DWorld”;
glutReshapeFunc(ChangeSize);
SetupRC();;
glutDisplayFunc(RenderScene);//用于绘制当前窗口;
glutMainLoop();//表示开始运行程序,用于程序的结尾;
return0;
}
voidDrawPoints(void)
{
inti;//Countingvariable
//Setpointsizelargertomakemorevisible
glPointSize(5.0f);
//Loopthroughallcontrolpointsforthisexample
glBegin(GL_POINTS);
for(i=0;i glVertex2fv(ctrlPoints[i]); glEnd(); } //Calledtodrawscene voidRenderScene(void) { inti; //Clearthewindowwithcurrentclearingcolor glClear(GL_COLOR_BUFFER_BIT); //Setsupthebezier //Thisactuallyonlyneedstobecalledonceandcouldgoin //thesetupfunction glMap1f(GL_MAP1_VERTEX_3,//Typeofdatagenerated 0.0f,//Lowerurange 100.0f,//Upperurange 3,//Distancebetweenpointsinthedata nNumPoints,//numberofcontrolpoints &ctrlPoints[0][0]);//arrayofcontrolpoints //Enabletheevaluator glEnable(GL_MAP1_VERTEX_3); //Usealinestripto"connect-the-dots" glBegin(GL_LINE_STRIP); for(i=0;i<=100;i++) { //Evaluatethecurveatthispoint glEvalCoord1f((GLfloat)i); } glEnd(); //Usehigherlevelfunctionstomaptoagrid,thenevaluatethe //entirething. //Putthesetwofunctionsintoreplaceaboveloop //Mapagridof100pointsfrom0to100 //glMapGrid1d(100,0.0,100.0); //Evaluatethegrid,usinglines //glEvalMesh1(GL_LINE,0,100); //DrawtheControlPoints DrawPoints(); //Flushdrawingcommands glutSwapBuffers(); } //Thisfunctiondoesanyneededinitializationontherendering //context. voidSetupRC() { //ClearWindowtowhite g
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验六 3D编程及Bezier曲线绘制 实验 编程 Bezier 曲线 绘制