您的位置:首页 > 运维架构

OpenGL系统设计

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

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: