Graphics 版 (精华区)

发信人: dht (bbs), 信区: Graphics
标  题:  OPENGL(13)
发信站: 紫 丁 香 (Sun Oct  4 21:51:03 1998), 转信

这里讲解OPENGL的曲线生成
1.曲线定义
void glMap1{fd}(GLenum target,TYPE u1,TYPE u2,GLint stride,
                GLint order,const TYPE *points);

target指出控制点的意义以及在points参数中需要多少值。具体如下:

target                                   意义
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纹理坐标

u1,u2是曲线变量U的范围(具体可以参阅图形学书籍)一般是0到1
stride是跨度,表示points中控制点偏移量(或说是控制点的维数)
order是阶数,与控制点数一样
points是控制点坐标
曲线定义后要启用才能进行绘制,同样用glEnable(),glDisable()。
2.曲线计算绘制
void glEvalCoord1{fd}[v](TYPE u);
利用控制点产生曲线U坐标下某点的坐标,调用一次只能产生一个坐标。
一般的曲线的绘制方法是让U变化从0到1(步长自定)然后把这些坐标
用直线连接起来。
用以上这两个函数就可以完成绘制曲线的功能。

另外还有两个函数可以实现类似功能:
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即延曲线绘点或连接直线段
它等价于:
glBegin(GL_POINT);
 for(i=p1;i<=p2;i++)
  glEvalCoord1(u1+i*(u2-u1)/n);
glEnd();
下面给出一个BEZIER曲线的例子:
////////////////////////////////////////////////////////////////////
//sample.cpp
#include "glos.h"
#include <GL/gl.h>
#include <GL/glaux.h>
#include "windows.h"
void myinit(void);
void CALLBACK  display(void);
void CALLBACK  reshape(GLsizei w,GLsizei h);

//定义四个控制点的坐标
GLfloat points[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)
{

        auxInitDisplayMode(AUX_SINGLE|AUX_RGBA);
        auxInitPosition(0,0,500,500);
        auxInitWindow("sample1");
        glClearColor(0.0,0.0,0.0,0.0);
        glClear(GL_COLOR_BUFFER_BIT);

//定义曲线,并启用绘制曲线的模式
        glMap1f(GL_MAP1_VERTEX_3,0.0,1.0,3,4,&points[0][0]);
        glEnable(GL_MAP1_VERTEX_3);

        glShadeModel(GL_FLAT);
}

void CALLBACK reshape(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)h/(GLfloat)w,
         5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0,-5.0,5.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

void CALLBACK display(void)
{
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  glColor3f(0.0,0.0,1.0);
  glBegin(GL_LINE_STRIP);
//首先以30步的直线段连接,来绘制曲线,注意使用GL_LINE_STRIP来连接直线段
  int i;
  for(i=0;i<=30;i++)
           glEvalCoord1f((GLfloat)i/30.0);
  glEnd();

//下面绘制出4个控制点
  glPointSize(4.0);
  glColor3f(1.0,0.0,0.0);
  glBegin(GL_POINTS);
  for(i=0;i<4;i++)
           glVertex3fv(&points[i][0]);
  glEnd();

  glFlush();

}
void main(void)
{
    myinit();

    auxReshapeFunc(reshape);
    auxMainLoop(display);
}
//end of sample
本例子绘制出一个有4个控制点的BEZIER曲线。曲线经过头尾两个控制点
中间曲线形状由控制点次序和位置决定,总之落在其包围的四边形以内。
下次将会用大篇幅介绍曲面的生成和其表面纹理、颜色的应用

--
※ 来源:.紫 丁 香 bbs.hit.edu.cn.[FROM: cadcam.hit.edu.c]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:3.148毫秒