OpenGL曲线曲面的绘制与3D模型的装载与显示.docx

上传人:b****5 文档编号:8168445 上传时间:2023-01-29 格式:DOCX 页数:24 大小:194.24KB
下载 相关 举报
OpenGL曲线曲面的绘制与3D模型的装载与显示.docx_第1页
第1页 / 共24页
OpenGL曲线曲面的绘制与3D模型的装载与显示.docx_第2页
第2页 / 共24页
OpenGL曲线曲面的绘制与3D模型的装载与显示.docx_第3页
第3页 / 共24页
OpenGL曲线曲面的绘制与3D模型的装载与显示.docx_第4页
第4页 / 共24页
OpenGL曲线曲面的绘制与3D模型的装载与显示.docx_第5页
第5页 / 共24页
点击查看更多>>
下载资源
资源描述

OpenGL曲线曲面的绘制与3D模型的装载与显示.docx

《OpenGL曲线曲面的绘制与3D模型的装载与显示.docx》由会员分享,可在线阅读,更多相关《OpenGL曲线曲面的绘制与3D模型的装载与显示.docx(24页珍藏版)》请在冰豆网上搜索。

OpenGL曲线曲面的绘制与3D模型的装载与显示.docx

OpenGL曲线曲面的绘制与3D模型的装载与显示

实验7OpenGL曲线、曲面的绘制与3D模型的装载与显示

实验目的:

1)理解Bezier曲线、曲面绘制的基本原理;理解OpenGL中一维、二维插值求值器的用法。

2)掌握OpenGL中曲线、曲面绘图的方法,对比不同参数下的绘图效果差异;

实验要求:

1)教师领读代码;

2)学生上机实验;

3)针对代码1,分别或同时去掉开关1和开关2的代码注释,查看并记录实验效果;用公式说明Bezier曲线、曲面的绘制计算过程;

4)针对代码2,分别或同时去掉各开关,观察并记录显示效果差异;用公式说明Bezier曲面插值点的计算过程;说明线框模型与曲面模型的区别;

5)针对代码3:

实验和观察材质参数、光照参数、坐标参数对实验效果的影响;

6)理解均匀与非均匀样条有理曲线或曲面的差异;

7)针对代码4:

掌握非均匀有理B样条曲面(NURBS曲面)的曲面绘制方法;

8)阅读

9)OpenGL如何装载并显示3DMAX导出的3D模型实验及代码,课外自行完成。

代码1:

用四个控制点绘制一条三次Bezier曲线:

//Demo:

用四个控制顶点来画一条三次Bezier曲线

#include

#include

#include

//4个控制点的3D坐标——z坐标全为0

GLfloatctrlpoints[4][3]={

{-4,-4,0},{-2,4,0},{2,-4,0},{4,4,0}

};

voidinit(void)

{

//背景色

glClearColor(0.0,0.0,0.0,1.0);

//将控制点坐标映射为曲线坐标

//参数:

GL_MAP1_VERTEX_3,3维点坐标

//参数2和3:

控制参数t或u的取值范围[0,1]

//参数4:

曲线内插值点间的步长3——3维坐标

//参数5:

曲线间的补偿为顶点数4个——总步长为12

//参数6:

控制点二维数组首元素地址

//note:

若是在这里设置了相关参数,后续对ctrlpoints内容更改曲线不变

glMap1f(GL_MAP1_VERTEX_3,0.0,1.0,3,4,&ctrlpoints[0][0]);

//打开开关——允许3维坐标控制点到参数点转换开关

glEnable(GL_MAP1_VERTEX_3);

glShadeModel(GL_FLAT);

//代码开关2:

去掉本注释,可启用反走样

/*

glEnable(GL_BLEND);

glEnable(GL_LINE_SMOOTH);//允许直线反走样

glHint(GL_LINE_SMOOTH_HINT,GL_FASTEST);//Antialiasthelines

glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

*/

}

voiddisplay(void)

{

inti;

glClear(GL_COLOR_BUFFER_BIT);

glColor3f(1.0,1.0,1.0);

//代码开关1:

去掉本注释,查看动态的曲线绘图效果:

动态更新控制点坐标

/*

for(intt=0;t<4;t++){

for(intj=0;j<3;j++)

ctrlpoints[t][j]=(rand()%1024/1024.0-0.5)*10;

}

//动态映射

glMap1f(GL_MAP1_VERTEX_3,0.0,1.0,3,4,&ctrlpoints[0][0]);

*/

glLoadIdentity();

glColor3f(1.0,0.0,0.0);

//绘制连续线段

glBegin(GL_LINE_STRIP);

//参数t或u取值为i/30,共计31个点

for(i=0;i<=30;i++)

glEvalCoord1f((GLfloat)i/30.0);//根据4个控制点坐标的参数化插值

glEnd();

/*显示控制点*/

glPointSize(5.0);

glBegin(GL_POINTS);

for(i=0;i<4;i++)

glVertex3fv(&ctrlpoints[i][0]);

glEnd();

glTranslatef(-0.1f,0.1f,0.0f);

glColor3f(0.0,1.0,0.0);

//glLineWidth(2.0);

//绘制连续线段——线段数越多,曲线越光滑

glBegin(GL_LINE_STRIP);

//设置参数t或u取值为i/60,共计61个点

//实验:

若让t从-2变化到+2,可看到什么效果

for(i=0;i<=60;i++)

glEvalCoord1f((GLfloat)i/60.0);//根据4个控制点坐标的参数化插值

glEnd();

glTranslatef(-0.1f,0.1f,0.0f);

glColor3f(1.0,1.0,1.0);

//绘制连续线段

glBegin(GL_LINE_STRIP);

//设置参数t或u取值为i/60,共计61个点

//实验:

若让t从-2变化到+2,可看到什么效果

for(i=0;i<=100;i++)

glEvalCoord1f((GLfloat)i/100.0);

glEnd();

glutSwapBuffers();

}

//3D空间中绘制2D效果,采用正交投影

voidreshape(GLsizeiw,GLsizeih)

{

glViewport(0,0,w,h);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

if(w<=h)

glOrtho(-5.0,5.0,-5.0*(GLfloat)h/(GLfloat)w,5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0);

else

glOrtho(-5.0*(GLfloat)w/(GLfloat)h,5.0*(GLfloat)w/(GLfloat)h,-5.0,5.0,-5.0,5.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

}

voidkeyboard(unsignedcharkey,intx,inty)

{//请参考"变换示例参考"一文,考虑添加键盘命令,交互式来控制金字塔的旋转

switch(key)

{

case'x':

case'X':

case27:

//ESC键

exit(0);

break;

default:

break;

}

}

intmain(intargc,char**argv)

{

srand((unsignedint)time(0));

glutInit(&argc,argv);

glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);//使用双缓存模式和深度缓存

glutInitWindowSize(800,800);

glutInitWindowPosition(0,0);

glutCreateWindow("2DBezier曲线");

init();

glutDisplayFunc(display);

glutReshapeFunc(reshape);

glutKeyboardFunc(keyboard);

glutIdleFunc(display);//设置空闲时调用的函数

glutMainLoop();

return0;

}

效果图:

动态曲线绘制效果图:

关闭代码开关1,打开代码开关2,查看直线反走样效果:

对比分析反走样前后曲线绘制效果差异。

代码2:

用4*4个控制点绘制一个三次Bezier曲面线框模型

//Demo:

用4*4个控制顶点来画一个三次Bezier曲面线框模型

#include

#include

#include

/*控制点的坐标*/

GLfloatctrlpoints[4][4][3]={

{{-1.5,-1.5,2.0},

{-0.5,-1.5,2.0},

{0.5,-1.5,-1.0},

{1.5,-1.5,2.0}

},

{{-1.5,-0.5,1.0},

{-0.5,1.5,2.0},

{0.5,0.5,1.0},

{1.5,-0.5,-1.0}},

{{-1.5,0.5,2.0},

{-0.5,0.5,1.0},

{0.5,0.5,3.0},

{1.5,-1.5,1.5}},

{{-1.5,1.5,-2.0},

{-0.5,1.5,-2.0},

{0.5,0.5,1.0},

{1.5,1.5,-1.0}}};

voidinit(void)

{

//背景色

glClearColor(0.0,0.0,0.0,1.0);

//将控制点坐标映射为曲面坐标

//参数:

GL_MAP1_VERTEX_3,3维点坐标

//参数2和3:

控制参数u的取值范围[0,1]

//参数4:

x方向元素间的步长为3个GLfloat

//参数5:

x方向曲线间的步长为4个控制点——曲线由4个控制点确定

//参数6-7:

控制参数v的取值范围[0,1]

//参数8:

y方向元素间的步长为12个GLfloat元素

//参数9:

y方向每条曲线的控制点数量为4

//note:

若是在这里设置了相关参数,后续对ctrlpoints内容更改曲线不变

glMap2f(GL_MAP2_VERTEX_3,0,1,3,4,0,1,12,4,&ctrlpoints[0][0][0]);

//允许二维映射

glEnable(GL_MAP2_VERTEX_3);

//二维映射:

x、y方向U和V的参数[0,1],且中间插值数量为各20个

glMapGrid2f(20,0.0,1.0,20,0.0,1.0);

//允许深度测试

glEnable(GL_DEPTH_TEST);

//代码开关2:

启用反走样

glEnable(GL_BLEND);

glEnable(GL_LINE_SMOOTH);

glHint(GL_LINE_SMOOTH_HINT,GL_FASTEST);//Antialiasthelines

glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

}

voiddisplay(void)

{

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glColor3f(0.0,1.0,0.0);

glPushMatrix();

//代码开关1:

去掉注释查看效果;更改旋转角度参数,查看效果

//glRotatef(0.1,1.0,1.0,1.0);

inti,j;

//生成2D网格坐标,以从控制点参数插值确定网格点所对应的点集所对应的坐标

for(j=0;j<=8;j++){

glBegin(GL_LINE_STRIP);

for(i=0;i<=30;i++)

glEvalCoord2f((GLfloat)i/30.0,(GLfloat)j/8.0);//固定y坐标时x方向的网格坐标

glEnd();

glBegin(GL_LINE_STRIP);

for(i=0;i<=30;i++)

glEvalCoord2f((GLfloat)j/8.0,(GLfloat)i/30.0);//固定x坐标时y方向的网格坐标

glEnd();

}

//查看网格所确定的插值点(u,v)的位置

glColor3f(1,0,0);

glBegin(GL_POINTS);

for(j=0;j<=8;j++){

for(i=0;i<=30;i++)

glVertex3f((GLfloat)i/30.0,(GLfloat)j/8.0,0);

for(i=0;i<=30;i++)

glVertex3f((GLfloat)j/8.0,(GLfloat)i/30.0,0);

}

glEnd();

glPopMatrix();

glutSwapBuffers();

}

voidreshape(GLsizeiw,GLsizeih)

{

glViewport(0,0,w,h);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

if(w<=h)

glOrtho(-5.0,5.0,-5.0*(GLfloat)h/(GLfloat)w,5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0);

else

glOrtho(-5.0*(GLfloat)w/(GLfloat)h,5.0*(GLfloat)w/(GLfloat)h,-5.0,5.0,-5.0,5.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

}

voidkeyboard(unsignedcharkey,intx,inty)

{//请参考"变换示例参考"一文,考虑添加键盘命令,交互式来控制金字塔的旋转

switch(key)

{

case'x':

case'X':

case27:

//ESC键

exit(0);

break;

default:

break;

}

}

intmain(intargc,char**argv)

{

srand((unsignedint)time(0));

glutInit(&argc,argv);

glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);//使用双缓存模式和深度缓存

glutInitWindowSize(800,800);

glutInitWindowPosition(0,0);

glutCreateWindow("Bezier曲面线框模型");

init();

glutDisplayFunc(display);

glutReshapeFunc(reshape);

glutKeyboardFunc(keyboard);

glutIdleFunc(display);//设置空闲时调用的函数

glutMainLoop();

return0;

}

效果:

未打开注释开关1时的效果:

打开注释开关1时的效果:

代码3:

用4*4个控制点绘制一个三次Bezier曲面并添加光照效果

//curve.cpp:

Definestheentrypointfortheconsoleapplication.

//

#include"stdafx.h"

//Demo:

用4*4个控制顶点来画一个三次Bezier曲面

#include

#include

#include

/*控制点的坐标*/

GLfloatctrlpoints[4][4][3]={

{{-1.5,-1.5,2.0},

{-0.5,-1.5,2.0},

{0.5,-1.5,-1.0},

{1.5,-1.5,2.0}},

{{-1.5,-0.5,1.0},

{-0.5,1.5,2.0},

{0.5,0.5,1.0},

{1.5,-0.5,-1.0}},

{{-1.5,0.5,2.0},

{-0.5,0.5,1.0},

{0.5,0.5,3.0},

{1.5,-1.5,1.5}},

{{-1.5,1.5,-2.0},

{-0.5,1.5,-2.0},

{0.5,0.5,1.0},

{1.5,1.5,-1.0}}};

voidinit(void)

{

//背景色

glClearColor(0.0,0.0,0.0,1.0);

//将控制点坐标映射为曲面坐标

//参数:

GL_MAP1_VERTEX_3,3维点坐标

//参数2和3:

控制参数u的取值范围[0,1]

//参数4:

x方向元素间的步长为3个GLfloat

//参数5:

x方向曲线间的步长为4个控制点——曲线由4个控制点确定

//参数6-7:

控制参数v的取值范围[0,1]

//参数8:

y方向元素间的步长为12个GLfloat元素

//参数9:

y方向每条曲线的控制点数量为4

//note:

若是在这里设置了相关参数,后续对ctrlpoints内容更改曲线不变

glMap2f(GL_MAP2_VERTEX_3,0,1,3,4,0,1,12,4,&ctrlpoints[0][0][0]);

//允许二维映射

glEnable(GL_MAP2_VERTEX_3);

//二维映射:

x、y方向U和V的参数[0,1],且中间插值数量为各20个

glMapGrid2f(20,0.0,1.0,20,0.0,1.0);

//允许深度测试

glDepthFunc(GL_LESS);

glEnable(GL_DEPTH_TEST);

//代码开关4:

取消下面两行代码,查看曲面显示效果差异

//打开自动法矢量开关

//glEnable(GL_AUTO_NORMAL);

//允许正则化法矢量

//glEnable(GL_NORMALIZE);

//代码开关3:

设置材质与光源

GLfloatambient[]={0.4,0.6,0.2,1.0};

GLfloatposition[]={0.0,1.0,3.0,1.0};

GLfloatmat_diffuse[]={0.2,0.4,0.8,1.0};

GLfloatmat_specular[]={1.0,1.0,1.0,1.0};

GLfloatmat_shininess[]={80.0};

glEnable(GL_LIGHTING);

glEnable(GL_LIGHT0);

glLightfv(GL_LIGHT0,GL_AMBIENT,ambient);

glLightfv(GL_LIGHT0,GL_POSITION,position);

glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);

glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);

glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);

}

voiddisplay(void)

{

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glColor3f(0.0,1.0,0.0);

//如果不希望旋转,则启用push和pop矩阵命令,并注释掉glRotatef行

//glPushMatrix();

//代码开关1:

去掉注释查看效果;更改旋转角度参数,查看效果

glRotatef(1.0,1.0,1.0,1.0);

glEvalMesh2(GL_FILL,0,20,0,20);

//glPopMatrix();

glutSwapBuffers();

}

voidreshape(GLsizeiw,GLsizeih)

{

glViewport(0,0,w,h);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

if(w<=h)

glOrtho(-5.0,5.0,-5.0*(GLfloat)h/(GLfloat)w,5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0);

else

glOrtho(-5.0*(GLfloat)w/(GLfloat)h,5.0*(GLfloat)w/(GLfloat)h,-5.0,5.0,-5.0,5.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

}

voidkeyboard(unsignedcharkey,intx,inty)

{//请参考"变换示例参考"一文,考虑添加键盘命令,交互式来控制金字塔的旋转

switch(key)

{

case'x':

case'X':

case27:

//ESC键

exit(0);

break;

default:

break;

}

}

intmain(intargc,char**argv)

{

srand((unsignedint)time(0));

glutInit(&argc,argv);

glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);//使用双缓存模式和深度缓存

glutInitWindowSize(800,800);

glutInitWindowPosition(0,0);

glutCreateWindow("Bezier曲面");

init();

glutDisplayFunc(display);

glutReshapeFunc(reshape);

glutKeyboardFunc(keyboard);

glu

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1