OpenGL系统设计

和曲线类似,曲面也可以通过控制点来模拟。实际上在很多场合也使用多边形来模拟平滑曲面,但使用控制点需要的计算机系统资源开销相对要少很多。同时,控制点个数越多,就越能够逼近真实的曲面,所以选择好的算法和适当的控制点个数相当重要。

OpenGL实现曲面的方法和曲线类似,它使用二维的glMap2和glEvalCoord2来代替glMap1和glEvalCoord1。同样,glMap2是设置二维曲面的定义(定义网格的运算子),glEvalCoord2计算具体的坐标点。两个函数的原型如下
 

void glMap2d(  GLenum target,  GLdouble u1,  GLdouble u2,  GLint ustride,  GLint uorder,  GLdouble v1,  GLdouble v2,  GLint vstride,  GLint vorder,  const GLdouble *points); void glMap2f(  GLenum target,  GLfloat u1,  GLfloat u2,  GLint ustride,  GLint uorder,  GLfloat v1,  GLfloat v2,  GLint vstride,  GLint vorder,  const GLfloat *points);target 参数含义和glMap1函数中的一样,取值也基本相同,只是把其中的GL_MAP1_*换成GL_MAP2_*。

u1, u2, v1,v2 含义同glMap1的u1,u2,只是从一维扩展到了二维。ustride, vstride相当于glMap1中的stride,uorder,vorder相当于order,points仍然是控制点数据指针。

glEvalCoord根据glMap的定义计算拟合过程坐标值,其函数原型如下,其中glEvalCoord1针对的是一维的曲线,而glEvalCoord2针对的是二维曲面。
 void glEvalCoord1d(  GLdouble u   ); void glEvalCoord1f(  GLfloat u   ); void glEvalCoord2d(  GLdouble u,    GLdouble v   ); void glEvalCoord2f(  GLfloat u,    GLfloat v   );void glEvalCoord1dv(  const GLdouble * u   ); void glEvalCoord1fv(  const GLfloat * u   ); void glEvalCoord2dv(  const GLdouble * u   ); void glEvalCoord2fv(  const GLfloat * u   );  其中u,v分别表示介于glMap定义的[u1 ,u2]、[v1,v2]范围之间的u,v值,计算用于拟合曲线或曲面的坐标值。

当函数原型是glEvalCoord*v时,表示参数是一个向量,如果是一维的,则该向量只有一个值,表示u值,如果是二维的,则表示有两个值,表示u和v。

 

Bezier曲面是Bezier曲线交织而成的曲面,BEZIER 曲线具有包络性,即三次BEZIER 曲线是二次BEZIER 曲线的簇的包络。N 次BEZIER曲面是N-1 次BEZIER 曲面的包络。另外,BEZIER 曲线还具有可分割性。下面我们来通过控制点来实现一个Bezier曲面的绘制。

 

 

//先定义20个控制点,u方向5个,v方向4个
GLfloat CtrlPoints[4][5][3] =

{

{{-1.5, 0.0, -2.0}, {-0.7, 0.7, -2.0},{0.0, 5.0, -2.0},

{0.7, 0.7, -2.0}, {1.5, 0, -2.0}},

 

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

{0.7, 0.707, -1.0}, {1.5, 0, -1.0}},

 

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

{0.7, 0.7, 1.0}, {1.5, 0, 1.0}},

 

{{-1.5, 0.0, 2.0}, {-0.7, 0.7, 2.0},{0.0, 5.0, 2.0},

{0.7, 0.7, 2.0}, {1.5, 0, 2.0}}

};

 

 

void glMain()

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();   //加载单位矩阵
glColor3f(0.0f, 0.0f, 0.0f);

glTranslatef(0.0f, -0.5f, -6.0f);

glRotatef(30, 1.0, 1.0, 1.0);

 

//设置曲面的控制点参数
glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 5, 0, 1, 15, 4, &CtrlPoints[0][0][0]);

glEnable(GL_MAP2_VERTEX_3);

 

//设置曲面网格的u、v值
glMapGrid2f(20, 0.0, 1.0, 20, 0.0, 1.0);

 

//开始绘制曲面网管
for (int j = 0; j <= 10; j++)

{

glBegin(GL_LINE_STRIP);

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

glEvalCoord2f((GLfloat)i/30.0, (GLfloat)j/10.0);

glEnd();

 

glBegin(GL_LINE_STRIP);

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

glEvalCoord2f((GLfloat)j/10.0, (GLfloat)i/30.0);

glEnd();

}

 

SwapBuffers(g_hDC);

}

 

程序运行效果如图10-10所示,可以看到一个马鞍状的网格曲面。

 

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/LotusOne/archive/2009/11/19/4838521.aspx

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/LotusOne/archive/2009/11/19/4838521.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值