Bezier曲面.doc

上传人:聆听****声音 文档编号:506204 上传时间:2023-04-29 格式:DOC 页数:8 大小:124KB
下载 相关 举报
Bezier曲面.doc_第1页
第1页 / 共8页
Bezier曲面.doc_第2页
第2页 / 共8页
Bezier曲面.doc_第3页
第3页 / 共8页
Bezier曲面.doc_第4页
第4页 / 共8页
Bezier曲面.doc_第5页
第5页 / 共8页
Bezier曲面.doc_第6页
第6页 / 共8页
Bezier曲面.doc_第7页
第7页 / 共8页
Bezier曲面.doc_第8页
第8页 / 共8页
亲,该文档总共8页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

Bezier曲面.doc

《Bezier曲面.doc》由会员分享,可在线阅读,更多相关《Bezier曲面.doc(8页珍藏版)》请在冰点文库上搜索。

Bezier曲面.doc

8

一、设计实验目的

通过实验可以更了解Bezier曲线曲面的概念,理解Bezier曲面生成的原理,加深对Bezier生成算法的理解,加强理论的学习,锻炼对知识的运用能力和实践能力;进一步对OpenGL强大功能的认识,并对一些函数如display()、makeImage()、init()、reshape(intw,inth)等的功能的运用又进一步的了解,为以后的学习打下基础。

二、设计实验要求

呈现Bezier曲面,并使其能够旋转和平移

三、实验原理

本程序用VisualC++Win32ConsoleApplicstion(32控制台应用程序)创建一个应用程序,再添加一个c++程序源—Bezier曲面。

绘制Bezier曲面主要运用多个多边形逼近而成,,并通过少数几个控制点对其进行描述。

通过定义曲面和均匀网格绘制一个具有光照和明暗处理效果的Bezier曲面,并实现曲面的放大和缩小,绕x轴,y轴,z轴旋转

四、算法分析:

下面给出程序中主函数中各函数功能说明:

glutInit(&argc,argv)初始化GLUT,用来接收来自main函数的参数,程序可以具体实现相关方式来使用这些参数。

glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH)颜色缓存的缓存模式,用于显示图形的颜色;

glutInitWindowSize(1000,600)函数功能是创建一个窗口大小为(1000,600);

glutInitWindowPosition(30,40)函数是所创建的窗口的(0,0)坐标在电脑窗口(30,40)出显示出来;

glutCreateWindow(argv[0])函数的功能实在屏幕上创建一个窗口;

glutDisplayFunc(display)函数display在每次对窗口重绘时使用;

glutReshapeFunc(reshape)函数主要是改变窗口大小的操作进行重绘;

glutMainLoop()是程序进入无限事件处理循环计算函数,该函数的调用应为main函数最后一条语句出现。

下面是各函数中的组成函数功能说明:

定义控制点坐标数组:

GLfloatctrlpoints[4][4][3]

绘制曲面(包含的代码描述了所要绘制的Bezier曲面)函数:

display()

生成图形的纹理函数:

makeImage()

负责状态变量初始化的函数:

init()

改变窗口大小的操作进行重绘的函数:

reshape()

程序进入无限事件处理循环计算函数:

glutMainLoop()

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)主要定义窗口底面颜色voidglEvalMesh2(GLenummode,GLintp1,GLintp2,GLintq1,GLintq2)的mode参数除了可以是GL_POINT和GL_LINE外,也可以是GL_FILL(生成填充空间曲面)。

voidglMap2{fd}(GLenumtarget,TYPEu1,TYPEu2,GLintustride,GLintuorder,TYPEv1,TYPEv2,Glintvstride,GLintvorder,TYPEpoints);

  这里target的意义与在glMap1*()中的意义相同;(u1,u2),(v1,v2)是二维曲面坐标;其他参数如uorder,vorder,ustride和vstride等的定义都类似于在曲线中的定义;points为控制点坐标。

对曲面任意一点的计算可通过函数

voidglEvalCoord2{fd}[v](TYPEu,TYPEv);

  来完成,通过在定义域内的曲线坐标值u,v来计算曲面内任意一点的世界坐标位置。

对于曲面,也可以象曲线一样通过函数来定义均匀间隔的曲面坐标值:

 voidglMapGrid2{fd}(GLenumnu,TYPEu1,TYPEu2,GLenumnv,TYPEv1,TYPEv2);

   该函数定义曲面参数空间均匀网格,从u1到u2分为等间隔nu步,从v1到v2分为等间隔nv步,然后由glEvalMesh2()将此网格应用到已经启动的曲面计算上。

一般来说,纹理图像为正方形或长方形。

但当它映射到一个多边形或曲面上并变换到屏幕坐标时,纹理的单个纹素很少对应于屏幕图像上的象素。

根据所用变换和所用纹理映射,屏幕上单个象素可以对应于一个纹素的一小部分(即放大)或一大批纹素(即缩小)。

下面用函数glTexParameteri()说明放大和缩小的方法:

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);

  实际上,第一个参数可以是GL_TEXTURE_1D或GL_TEXTURE_2D,即表明所用的纹理是一维的还是二维的;第二个参数指定滤波方法,其中参数值GL_TEXTURE_MAG_FILTER指定为放大滤波方法,GL_TEXTURE_MIN_FILTER指定为缩小滤波方法。

  若选择GL_NEAREST则采用坐标最靠近象素中心的纹素,这有可能使图像走样;若选GL_LINEAR则采用最靠近象素中心的四个象素的加权平均值。

GL_NEAREST所需计算比GL_LINEAR要少,因而执行得更快,但GL_LINEAR提供了比较光滑的效果。

GLfloatambient[4]={0.8,0.6,0.4,1.0}定义初始化光照、材质的过程

GLfloatposition[4]={0.0,1.0,3.0,1.0}为定义一个黄色光源

GLfloatmat_diffuse[4]={0.8,0.2,0.1,1.0}是定义特定颜色的镜面反射

GLfloatmat_specular[4]={0.8,0.6,0.3,1.0}是定义镜面反射的光亮度

GLfloatmat_shininess[1]={60.0}为光源发光的角度

五、源程序:

#include

#include

#include

GLfloatctrlpoints[4][4][3]={//控制点坐标

{{-1.5,-1.5,4.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,-0.5,3.0},{0.5,-0.5,0.0},{1.5,-0.5,-1.0}},

{{-1.5,0.5,4.0},{-0.5,0.5,0.0},{0.5,0.5,3.0},{1.5,0.5,4.0}},

{{-1.5,1.5,-2.0},{-0.5,1.5,-2.0},{0.5,1.5,0.0},{1.5,1.5,-1.0}}

};

GLfloattheta[3]={0.0,0.0,0.0};

GLfloatd=0;

GLfloattexpts[2][2][2]={{{0.0,0.0},{0.0,1.0}},{{1.0,0.0},{1.0,1.0}}};

voiddisplay(void)

{

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glColor3f(1.0,1.0,1.0);

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

glFlush();

glutSwapBuffers();

}

#define imageWidth64

#define imageHeight64

GLbyteimage[3*imageWidth*imageHeight];

voidmakeImage(void)

{

inti,j;

floatti,tj;

for(i=0;i

ti=2.0*3.14159265*i/imageWidth;

for(j=0;j

tj=2.0*3.14159265*j/imageHeight;

image[3*(imageHeight*i+j)]=(GLubyte)127*(1.0+sin(ti));

image[3*(imageHeight*i+j)+1]=(GLubyte)127*(1.0+cos(2*tj));

image[3*(imageHeight*i+j)+2]=(GLubyte)127*(1.0+cos(ti+tj));

}

}

}

voidinit(void)

{

glClearColor(0.0,0.0,0.0,1.0);//清屏

glEnable(GL_DEPTH_TEST);//激活深度比较

glMap2f(GL_MAP2_VERTEX_3,0,1,3,4,0,1,12,4,&ctrlpoints[0][0][0]);//定义曲面

glMap2f(GL_MAP2_TEXTURE_COORD_2,0,1,2,2,0,1,4,2,&texpts[0][0][0]);

glEnable(GL_MAP2_TEXTURE_COORD_2);//启动曲面

glEnable(GL_MAP2_VERTEX_3);

glEnable(GL_MAP2_VERTEX_3);//启用曲面

glEnable(GL_AUTO_NORMAL);//启用曲面法向向量计算

glEnable(GL_NORMALIZE);//启用法向归一化

glMapGrid2f(20,0.0,1.0,20,0.0,1.0);//定义参数空间的均匀网格

GLfloatambient[4]={0.8,0.6,0.4,1.0};//初始化光照、材质的过程

GLfloatposition[4]={0.0,1.0,3.0,1.0};//定义一个黄色光源

GLfloatmat_diffuse[4]={0.8,0.2,0.1,1.0};//定义特定颜色的镜面反射

GLfloatmat_specular[4]={0.8,0.6,0.3,1.0};//定义镜面反射的光亮度

GLfloatmat_shininess[1]={60.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);

//makeImage();

glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);

glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,imageWidth,imageHeight,0,

GL_RGB,GL_UNSIGNED_BYTE,image);//定义一个二维纹理映射

glEnable(GL_DEPTH_TEST);

}

staticvoidmouse(intbutton,intstate,intx,inty)

{

if(state==GLUT_DOWN&&button==GLUT_LEFT_BUTTON)

{

d=1.2;

glScalef(d,d,d);

glutPostRedisplay();

}

if(state==GLUT_DOWN&&button==GLUT_RIGHT_BUTTON)

{

d=0.8;

glScalef(d,d,d);

glutPostRedisplay();

}

}

voidkeyboard(unsignedcharkey,intx,inty)

{

switch(key){

case't':

case'T':

glutPostRedisplay();

break;

case27:

exit(0);

break;

case'x':

case'X':

theta[0]+=5;

if(theta[1]>360)theta[0]-=360;

glRotatef(theta[0],1.0,0.0,0.0);

glutPostRedisplay();

break;

case'y':

case'Y':

theta[1]+=5;

if(theta[1]>360)theta[1]-=360;

glRotatef(theta[1],0.0,10.0,0.0);

glutPostRedisplay();

break;

case'z':

case'Z':

theta[2]+=5;

if(theta[2]>360)theta[2]-=360;

glRotatef(theta[2],0.0,0.0,1.0);

glutPostRedisplay();

break;

default:

break;

}

}

voidreshape(intw,inth)

{

glViewport(0,0,(GLsizei)w,(GLsizei)h);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

if(w<=h)

glOrtho(-4.0,4.0,-4.0*(GLfloat)h/(GLfloat)w,

4.0*(GLfloat)h/(GLfloat)w,-4.0,4.0);

else

glOrtho(-4.0*(GLfloat)w/(GLfloat)h,

4.0*(GLfloat)w/(GLfloat)h,-4.0,4.0,-4.0,4.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

glRotatef(85.0,1.0,1.0,1.0);

}

intmain(intargc,char**argv)

{

glutInit(&argc,argv);

glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);

glutInitWindowSize(800,600);

glutInitWindowPosition(50,40);

glutCreateWindow(argv[0]);

init();

glutDisplayFunc(display);

glutIdleFunc(NULL);

glutMouseFunc(mouse);

glutKeyboardFunc(keyboard);

glutReshapeFunc(reshape);

glutMainLoop();

return0;

}

六、实验输出结果显示

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

当前位置:首页 > IT计算机 > 电脑基础知识

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2