发信人: yxy (田丝丝#冬眠的小肥鹰), 信区: GAME_Designer 
标  题: OPENGL(13) 
发信站: BBS 水木清华站 (Mon Feb 16 21:40:42 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 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 166.111.74.90]