在VC中使用OpenGL绘制典型曲面_第1页
在VC中使用OpenGL绘制典型曲面_第2页
在VC中使用OpenGL绘制典型曲面_第3页
在VC中使用OpenGL绘制典型曲面_第4页
在VC中使用OpenGL绘制典型曲面_第5页
已阅读5页,还剩1页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、在VC+中使用OpenGL绘制典型曲面摘要: 本文主要讨论了在VC+中使用OpenGL绘制Bezier、NURBS等典型曲面的一般性方法。关键词: OpenGL;Bezier;NURBS;曲面绘制 OpenGL中对复杂物体的建摸基本几何图元是OpenGL进行建模的最基本的方法,但其对较复杂真实物体的建模则比较困难。对于这些复杂物体的建模,需要用到OpenGL基本库和功能库函数(gl库和glu库)以对图元进行扩展并完成法向计算、曲线生成和曲面构造等内容。这种对基本图元的扩展实际也就是对点、线及多边形的扩展。OpenGL中定义的点可具有不同大小的尺寸,其扩展的函数形式为:void glPointS

2、ize(GLfloat size); 其参数size以象素为单位设置了点的宽度,其值必须为正,缺省值1.0。对于线的扩展,可通过下面的函数来分别指定其宽度和绘制类型: void glLineWidth(GLfloat width);void glLineStipple(GLint factor,GLushort pattern); glLineWidth()的参数width以象素为单位指定线宽,其值必须为正,缺省值为1.0。glLineStipple()的参数factor为对模式进行拉伸的比例因子,参数pattern指定了线的模式(例如11001100将绘制一条虚线,为1时绘制,为0时不绘制)

3、。该函数只有在启用了函数glEnable(GL_LINE_STIPPLE)后才可以使用,当不再使用时调用glDisable(GL_LINE_STIPPLE)将其关闭。扩展多边形的绘制模式包括全填充式、轮廓点式、轮廓线式及图案填充式等几种。使用时,首先调用glPolygonMode()设置多边形的模式设置:void glPolygonMode(GLenum face,GLenum mode); 参数face为GL_FRONT、GL_BACK或GL_FRONT_AND BACK;mode取值可以是GL_POINT、GL_LINE或GL_FILL,分别表示多边型的轮廓点、轮廓线和填充模式的绘制方式。

4、缺省设置为填充模式。设置完成后可进行图案填充的设置:void glPolygonStipple(const GLubyte *mask); 其参数mask必须为一指向32×32大小的位图的指针,值为1时绘制、为0不绘制。该函数的使用同样也需要进行如下启动、关闭设置:glEnable(GL_POLYGON-STIPPLE);glDisable(GL_POLYGON_STIPPLE); 复杂模型的建模不同与简单模型的建模,在简单模型中一个平面上各点的法向(mormal vector)是一样的,均等于此平面的法向。对于复杂模型中由众多小的平面多边形逼近而成的曲面,其每个顶点的法向量都不一样

5、,因此曲面上每个点的法向计算结果根据采取的不同算法而有不同的结果。OpenGL只提供赋予当前顶点法向量的函数,而不提供对法向量计算的方法,法向量的计算需要由开发者来完成。下面给出一种简单的计算方法:void getNormal(GLfloat gx3,GLfloat gy3,GLfloat gz3,GLfloat *ddnv)GLfloat w0,w1,w2,v0,v1,v2,nr,nx,ny,nz;w0=gx0-gx1; w1=gy0-gy1;w2=gz0-gz1;v0=gx2-gx1;v1=gy2-gy1;v2=gz2-gz1;nx=(w1*v2-w2*v1);ny=(w2*v0-w0*v

6、2);nz=(w0*v1-w1*v0);nr=sqrt(nx*nx+ny*ny+nz*nz);ddnv0=nx/nr;ddnv1=ny/nr; ddnv2=nz/nr; 其参数gx3,gy3和gz3为逼近曲面的一个三角形的三个顶点P0,P1和P2。通过计算矢量P0-P1与矢量P2-P1的叉乘而得到其平面法向量,并在归一化后保存到由参数ddnv所指向的数组中。至于顶点法向的计算则多是取邻近平面法向量的均值。OpenGL提供的法向定义函数为:void glNormal3bsifd(TYPE nx,TYPE ny,TYPE nz);void glNormal3bsifdv(const TYPE *v

7、); 通过这两个函数可以设置当前法向值。对于非向量形式的定义采用前一种方式,通过参数nx、ny和nz分别给出法向三个分量值;对于向量形式的定义采取后一种方式,将v设置为指向法向三分量的指针。在应用时,通常要对法向进行归一化处理。构造曲线、曲面在进行复杂物体建模时,使用的光滑曲线、曲面都是由一些线段和多边形逼近而成,并通过少数几个控制点对其进行描述。曲线的定义由glMap1*()函数完成:void glMap1fd(GLenum target,TYPE u1,TYPE u2,GLint stride, GLint order,const TYPE *points); 参数target指出了控制顶

8、点的意义以及在points参数中需要提供多少值;points指针可以指向控制点集、RGBA颜色值或是纹理坐标串等。参数u1和u2限定了变量U的取值范围,通常是从0变化到1;stride表示跨度(在每块存储区内浮点数或双精度数的个数,即两个控制点间的偏移量);最后的参数order为阶数,是次数加1,与控制点数一致。曲线定义后必须再glEnable()函数显式启动后才能起作用,其参数与target保持一致。在使用完毕后通过glDisable()函数将其关闭。曲线坐标可通过glEvalCoord1*()函数进行计算:void glEvalCoord1fdv(TYPE u); 该函数将产生曲线坐标值并

9、将其绘制。参数u为定义域内的任意值,每调用一次将只产生一个坐标,此坐标值也是任意的。但目前较多采用的是定义均匀间隔曲线坐标值,依次调用glMapGrid1*()和glEvalMesh1()可以获得等间隔值。这两个函数分别用来定义一个一维网格和计算相应的坐标值。曲面的构造可以是网格线和填充曲面形式,与曲线的构造很类似只是将其扩展为二维而已。下面给出曲面的定义函数:void glMap2fd(GLenum target,TYPE u1,TYPE u2,GLint ustride,GLint uorder,TYPE v1,TYPE v2,GLint vstride,GLint vorder,TYPE

10、 points); 这里target的意义与在glMap1*()中的意义相同;(u1,u2),(v1,v2)是二维曲面坐标;其他参数如uorder,vorder,ustride和vstride等的定义都类似于在曲线中的定义;points为控制点坐标。对曲面任意一点的计算可通过函数void glEvalCoord2fdv(TYPE u,TYPE v); 来完成,通过在定义域内的曲线坐标值u,v来计算曲面内任意一点的世界坐标位置。对于曲面,也可以象曲线一样通过函数来定义均匀间隔的曲面坐标值:void glMapGrid2fd(GLenum nu,TYPE u1,TYPE u2, GLenum nv

11、,TYPE v1,TYPE v2);void glEvalMesh2(GLenum mode,GLint p1,GLint p2,GLint q1,GLint q2); 第一个函数定义曲面参数空间均匀网格,从u1到u2分为等间隔nu步,从v1到v2分为等间隔nv步,然后由glEvalMesh2()将此网格应用到已经启动的曲面计算上。glEvalMesh2()的mode参数除了可以是GL_POINT和GL_LINE外,也可以是GL_FILL(生成填充空间曲面)。 Bezier曲面的绘制下面给出一个通过定义曲面和均匀网格绘制一个具有光照和明暗处理效果的Bezier曲面(图1)的部分主要代码:GLf

12、loat ctrlpoints443 = / 控制点坐标-2.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, -1.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;void Init()glClearColor

13、(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, &ctrlpoints000);/ 定义曲面glEnable(GL_MAP2_VERTEX_3); / 启用曲面glEnable(GL_AUTO_NORMAL); / 启用曲面法向向量计算glEnable(GL_NORMALIZE); / 启用法向归一化glMapGrid2f(20, 0.0, 1.0, 20, 0.0, 1.0); / 定义参数空间的均匀网格GLfloat ambi

14、ent4 = 0.4, 0.6, 0.2, 1.0; / 初始化光照、材质的过程GLfloat position4 = 0.0, 1.0, 3.0, 1.0;GLfloat mat_diffuse4 = 0.8, 0.6, 0.3, 1.0;GLfloat mat_specular4 = 0.8, 0.6, 0.3, 1.0;GLfloat mat_shininess1 = 45.0;glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);glLightfv(GL_LIGHT0, G

15、L_POSITION, position);glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);图1 绘制的Bezier曲面NURBS曲面的绘制上面的例程通过给定少量控制点就可以很好的控制曲面的形状。在实际应用时也可以通过程序来动态生成或调整控制点。在本例中,对曲面的定义等操作均是显示调用本节前面介绍的glMap2f()、glMapGrid2f()等

16、函数来实现的。除了这种方式,还可以利用OpenGL的功能库提供的绘制非均匀有理B样条曲面(NURBS曲面)的函数进行曲面绘制,下面给出实现此功能的部分示例代码:GLfloat ctlpoints443; / 控制点的存储空间GLUnurbsObj *theNurb; / 指向NURBS曲面对象的指针void InitSurface()int u, v;for (u = 0; u < 4; u+) for (v = 0; v < 4; v+) ctlpointsuv0 = 2.0 * (GLfloat)u - 1.5);ctlpointsuv1 = 2.0 * (GLfloat)v

17、- 1.5);if (u = 1 | u = 2) && (v = 1 | v = 2) ctlpointsuv2 = 6;else ctlpointsuv2 = -6;void Init(void)GLfloat mat_diffuse = 0.8, 0.6, 0.3, 1.0; / 定义曲面材质 GLfloat mat_specular = 0.8, 0.6, 0.3, 1.0;GLfloat mat_shininess = 45.0;glClearColor(0.0, 0.0, 0.0, 1.0);glMaterialfv(GL_FRONT, GL_DIFFUSE, ma

18、t_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);glDepthFunc(GL_LESS);glEnable(GL_DEPTH_TEST);glEnable(GL_AUTO_NORMAL);glEnable(GL_NORMALIZE);InitSurface(); / 初始化控制点theNurb = gluNewNurbsRenderer(); / 创建一个NURBS曲面对象/ 修改NURBS曲面对象的属性gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, 5.0);gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_FILL);void CALLBACK Display()GLfloat knots8 = 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0; / NUR

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论