hyde
路人甲
路人甲
  • 注册日期2003-09-24
  • 发帖数555
  • QQ
  • 铜币1457枚
  • 威望0点
  • 贡献值0点
  • 银元0个
阅读:1204回复:0

OpenGL系列讲座(19)

楼主#
更多 发布于:2004-03-21 11:06
3.3 曲线生成
 

计算机图形学中,所有的光滑曲线都采用线段逼近来模拟,而且许多有用的曲线在数学

上只用少数几个参数(如控制点等)来描述。本节简要地介绍一下OpenGL中Bezier曲线的

绘制方法。

 

 

3.3.1 曲线绘制举例

 

下面我们来看一个简单的例子,这是用四个控制顶点来画一条三次Bezier曲线。程序如

下 bzcurve.c :

 

例 3-8  Bezier曲线绘制例程 bzcurve.c

 

#include "glos.h"

 

#include <GL/gl.h>

#include <GL/glu.h>

#include <GL/glaux.h>

 

void myinit(void);

void CALLBACK myReshape(GLsizei w, GLsizei h);

void CALLBACK display(void);

 

GLfloat ctrlpoints[4][3] = {

    { -4.0, -4.0, 0.0}, { -2.0, 4.0, 0.0},

    {2.0, -4.0, 0.0}, {4.0, 4.0, 0.0}};

 

void myinit(void)

{

    glClearColor(0.0, 0.0, 0.0, 1.0);

    glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]);

    glEnable(GL_MAP1_VERTEX_3);

    glShadeModel(GL_FLAT);

}

 

void CALLBACK display(void)

{

    int i;

 

    glClear(GL_COLOR_BUFFER_BIT);

    glColor3f(1.0, 1.0, 1.0);

    glBegin(GL_LINE_STRIP);

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

        glEvalCoord1f((GLfloat) i/30.0);

    glEnd();

 

/* 显示控制点  */

    glPointSize(5.0);

    glColor3f(1.0, 1.0, 0.0);

    glBegin(GL_POINTS);

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

        glVertex3fv(&ctrlpoints[0]);

    glEnd();

    glFlush();

}

 

void CALLBACK myReshape(GLsizei w, GLsizei h)

{

    glViewport(0, 0, w, h);

    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();

    if (w <= h)

    glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w,

        5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0);

    else

    glOrtho(-5.0*(GLfloat)w/(GLfloat)h,

        5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0);

    glMatrixMode(GL_MODELVIEW);

    glLoadIdentity();

}

 

void  main(void )

{

    auxInitDisplayMode (AUX_SINGLE | AUX_RGBA);

    auxInitPosition (0, 0, 500, 500);

    auxInitWindow ("Bezier Curves");

    myinit();

    auxReshapeFunc (myReshape);

    auxMainLoop(display);

}

 

  

 

图 3-3-7 一条光滑的Bezier曲线

 

3.3.2 曲线定义和启动

 

    OpenGL中曲线定义的函数为:

 

void glMap1{fd}(GLenum target,TYPE u1,TYPE u2,GLint stride,

                GLint order,const TYPE *points);

 

函数的第一个参数target指出控制顶点的意义以及在参数points中需要提供多少值,

具体值见表3-3-1所示。参数points指针可以指向控制点集、RGBA颜色值或纹理坐标串等。

例如若target是GL_MAP1_COLOR_4,则就能在RGBA四维空间中生成一条带有颜色信息的曲

线,这在数据场可视化中应用极广。参数u1和u2,指明变量U的范围,U一般从0变化到1。

参数stride是跨度,表示在每块存储区内浮点数或双精度数的个数,即两个控制点间的偏移

量,比如上例中的控制点集ctrpoint[4][3]的跨度就为3,即单个控制点的坐标元素个数。

函数参数order是次数加1,叫阶数,与控制点数一致。

 

________________________________________________________________________

 

    参  数                            意    义

________________________________________________________________________

 

GL_MAP1_VERTEX_3             x,y,z   顶点坐标

GL_MAP1_VERTEX_4             x,y,z,w 顶点坐标

GL_MAP1_INDEX                颜色表

GL_MAP1_COLOR_4              R,G,B,A

GL_MAP1_NORMAL               法向量

GL_MAP1_TEXTURE_COORD_1      s        纹理坐标

GL_MAP1_TEXTURE_COORD_2      s,t      纹理坐标

GL_MAP1_TEXTURE_COORD_3      s,t,r    纹理坐标

GL_MAP1_TEXTURE_COORD_4      s,t,r,q  纹理坐标

________________________________________________________________________

 

               表3-3-1  用于glMap1*()控制点的数据类型

 

 

曲线定义后,必须要启动,才能进行下一步的绘制工作。启动函数仍是glEnable(),其

中参数与glMap1*()的第一个参数一致。同样,关闭函数为glDisable(),参数也一样。

 

 

3.3.3 曲线坐标计算

 

   这里提到的坐标概念是广义的,与以前定义的有点不同,具体地说就是表3-3-1所对应的

类型值。OpenGL曲线坐标计算的函数形式如下:

 

void glEvalCoord1{fd}[v](TYPE u);

 

    产生曲线坐标值并绘制。参数u是定义域内的值,这个函数调用一次只产生一个坐标。

 

 

3.3.4 定义均匀间隔曲线坐标值

 

在使用glEvalCoord1*()计算坐标,因为u可取定义域内的任意值,所以由此计算出的

坐标值也是任意的。但是,目前用得最普遍的仍是取等间隔值。要获得等间隔值,OpenGL提

供了两个函数,即先调用glMapGrid1*()定义一个一维网格,然后用glEvalMesh1()计算响应

的坐标值。

 

    下面详细解释这两个函数:

 

void glMapGrid1{fd}(GLint n,TYPE u1,TYPE u2);

 

定义一个网格,从u1到u2分为n步,它们是等间隔的。实际上,这个函数定义的是参

数空间网格。

 

void glEvalMesh1(GLenum mode,GLint p1,GLint p2);

 

计算并绘制坐标点。参数mode可以是GL_POINT或GL_LINE,即沿曲线绘制点或沿曲线

绘制相连的线段。这个函数的调用效果同在p1和p2之间的每一步给出一个glEvalCoord1()

的效果一样。从编程角度来说,除了当i=0或i=n,它准确以u1或u2作为参数调用glEvalCoord1()

之外,它等价于一下代码:

 

glBegin(GL_POINT);  /* glBegin(GL_LINE_STRIP);  */

  for(i=p1;i<=p2;i++)

     glEvalCoord1(u1+i*(u2-u1)/n);

glEnd();

 

 

 

喜欢0 评分0
夜落了,风静了,我喜欢一本书,一杯茶,一粒摇曳的烛光...
游客

返回顶部