您的位置: 旅游网 > 网红

VC下利用OpenGL构造自由型曲线曲面

发布时间:2019-09-13 20:52:23

对自由型曲线曲面的绘制

OpenGL的一个很大的优点就是在绘制构造三维实体的光滑曲线和曲面时只需少量控制点就完成了对其的精确描述,而不必靠大量的基本图元去拟合。NURBS就是我们熟悉的B样条的扩展,只不过引入了权因子并以有理分式表示其曲线。因此用OpenGL的NURBS编程接口绘制自由型曲线曲面只需预先对节点序列和控制点进行定义即可完成对NURBS样条的精确描述:

//节点序列

GLfloat Notes[8]={0.0f,0.0f,0.0f,0.0f,1.0f,1.0f,1.0f,1.0f};

//定义控制点

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

{

for(int j=0;j<4;j++)

{

LinchpinPt[i][j][0]=(GLfloat)(3.0f*(i-0.5f));

LinchpinPt[i][j][1]=(GLfloat)(3.0f*(j-0.5f));

if(0<i && i<3 && 0<j && j<3)

LinchpinPt[i][j][2]=4.0f;

else

LinchpinPt[i][j][2]=-4.0f;

}

}

使用OpenGL提供的NURBS编程接口进行编程比较简洁:首先创建一个NURBS曲面对象并根据需要对其属性进行设置,在调用了gluBeginSurface()或是gluBeginCurve()后就可以根据前面定义的控制点对其曲线曲面进行绘制了,绘制完毕后以gluEndSurface()或gluEndCurve()结束:

//创建NURBS曲面对象

Nurb=gluNewNurbsRenderer();

//设置NURBS曲面对象属性

gluNurbsProperty(Nurb,GLU_SAMPLING_TOLERANCE,30.0f);

gluNurbsProperty(Nurb,GLU_DISPLAY_MODE,GLU_FILL);

//开始NURB区间绘制

gluBeginSurface(Nurb);

//定义NURBS曲面的形状

gluNurbsSurface(Nurb,8,Notes,8,

Notes,4*3,3,

&LinchpinPt[0][0][0],

4,4,GL_MAP2_VERTEX_3);

//结束曲面绘制

gluEndSurface(Nurb);

glPopMatrix();

//强制绘图,不驻留缓存

glFlush();

其中gluNurbsSurface()是定义NURBS曲线曲面的关键函数,其函数原型定义如下:

void gluNurbsSurface(

GLUnurbsObj * nobj,    //NURBS曲面对象

GLint sknot_count, //u方向节点数目

GLfloat * sknot, //u方向节点数组指针

GLint tknot_count, //v方向节点数目

GLfloat * tknot, //v方向节点数组指针

GLint s_stride, //u方向控制点数据跨度

GLint t_stride, //v方向控制点数据跨度

GLfloat * ctlarray, //控制点数组指针

GLint sorder, //u方向上多项式阶数

GLint torder, //v方向上多项式阶数

GLenum type //确定求值器类型

);

另有一gluNurbsCurve()函数也可用于对NURBS曲线曲面的定义,具体使用方法与之类似。

光照和材质的渲染

为更真实地对实体进行三维建模,需要对已构造成型的自由型曲线曲面进行光照和材质上的渲染。OpenGL对此提供有一系列的用于建立光照模型的库函数,使用户可以很方便地在三维场景中建立所需的光照模型。OpenGL中的光照模型由环境光(Ambient Light)、漫射光(Diffuse Light)、镜面反射光(Specular Light)等组成,同时还可设置光线衰减因子来模拟真实的光源效果。下面这段代码定义了一个黄色光源:

GLfloat Light_position[]={1.0f,1.0f,1.0f,0.0f,};

GLfloat Light_diffuse[]={1.0f,1.0f,0.0f,1.0f,};

glLightfv(GL_LIGHT0,GL_POSITION,Light_position); //定义光源位置

glLightfv(GL_LIGHT0,GL_DIFFUSE,Light_diffuse); //定义光源漫射光

glEnable(GL_AUTO_NORMAL); //自动生成曲面法向量

glEnable(GL_LIGHTING); //启动光照模型;

glEnable(GL_LIGHT0); //使光源GL_LIGHT0有效

其中glEnable(GL_AUTO_NORMAL)函数可以自动生成曲面法向量来对光照进行处理。OpenGL里提供了GL_LIGHT0~GL_LIGHT7八个光源,在这里glEnable()使用的是GL_LIGHT0光源。虽然通过定义光源可以提高一定的真实度,但对三维实体的材质定义更可大幅提高程 序所绘制曲面的逼真程度。OpenGL中所指的材质均指构成三维实体的材料在光照模型中对于R、G、B三原色的反射率。与光源的定义类似,材质的定义分环境、漫射、 镜面反射等成分,另外还有镜面高光指数、辐射成分等等:

//设置材质的反射成分

GLfloat mat_ambient[]={0.8f,0.8f,0.8f,1.0f};

GLfloat mat_diffuse[]={0.8f,0.0f,0.0f,1.0f}; //紫色

GLfloat mat_specular[]={1.0f,0.0f,1.0f,1.0f}; //镜面高光亮紫色

GLfloat mat_shininess[]={100.0f}; //高光指数

glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient); //定义环境光反射率

glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse); //定义漫射光反射率

glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular); //定义镜面光反射率

glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess); //定义高光指数

OpenGL中材质的颜色与光照模型中光源的颜色含义是不同的。对于在光源中的定义,R、G、B分别表示三原色在光源中所占的比率;而对于材质的定义,R、G、B则表示具有这种材质属性的物体对于三原色的反射率,场景中物体所呈现的颜色是光照模型、材质定义共同作用的结果。

结论

本文通过OpenGL辅助库提供的NURBS编程接口,在VC++下对自由型曲线曲面进行了绘制,并介绍了对其曲面的光照和材质的渲染方法。通过对本文的理解可以通过OpenGL绘制自由型曲线曲面来更好的对三维实体进行建模,并可进一步感受到OpenGL在三维图形计算机应用中的微妙之处。

查看本文来源

早期心肌梗死如何治疗
小孩脾胃虚弱用药
小便刺痛不治疗方法
宝宝消化不良又吐又拉
猜你会喜欢的
猜你会喜欢的