OpenGL系统设计-扩展建模(6)

 

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

OpenGL实现曲面的方法和曲线类似,它使用二维的glMap2glEvalCoord2来代替glMap1glEvalCoord1。同样,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 v1v2 含义同glMap1u1u2,只是从一维扩展到了二维。ustride vstride相当于glMap1中的strideuordervorder相当于orderpoints仍然是控制点数据指针。

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   
);
 
 

其中uv分别表示介于glMap定义的[u1 ,u2][v1,v2]范围之间的uv值,计算用于拟合曲线或曲面的坐标值。

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

 

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);

 

//设置曲面网格的uv

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所示,可以看到一个马鞍状的网格曲面。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值