1. 程式人生 > >圖解opengl曲線和曲面繪製

圖解opengl曲線和曲面繪製

VC6 下載
http://blog.csdn.net/bcbobo21cn/article/details/44200205

opengl環境配置
http://blog.csdn.net/bcbobo21cn/article/details/51044614#t4

以下的demo工程

http://pan.baidu.com/s/1kVGmRAJ

一 使用二維求值器繪製一個曲面

#include <windows.h>
#include <GL/GLAUX.h>
#include <GL/glut.h>
#include <math.h> 
//GLfloat ctrlpoints[5][5][3] = {{{-2,0,0},{-1,1,0},{0,0,0},{1,-1,0},{2,0,0}},
//{{-2,0,-1},{-1,1,-1},{0,0,-1},{1,-1,-1},{2,0,-1}},
//{{-2,0,-2},{-1,1,-2},{0,0,-2},{1,-1,-2},{2,0,-2}},
//{{-2,0,-3},{-1,1,-3},{0,0,-3},{1,-1,-3},{2,0,-3}},
//{{-2,0,-4},{-1,1,-4},{0,0,-4},{1,-1,-4},{2,0,-4}}};
 
GLfloat ctrlpoints[5][5][3] = {{{-3,0,0},{-1,1,0},{0,0,0},{1,-1,0},{3,0,0}},
{{-3,0,-1},{-1,1,-1},{0,0,-1},{1,-1,-1},{3,0,-1}},
{{-3,0,-3},{-1,1,-3},{0,0,-3},{1,-1,-3},{3,0,-3}},
{{-3,0,-3},{-1,1,-3},{0,0,-3},{1,-1,-3},{3,0,-3}},
{{-3,0,-4},{-1,1,-4},{0,0,-4},{1,-1,-4},{3,0,-4}}};
 
GLfloat mat_ambient[] = {0.1,0.1,0.1,1.0};
GLfloat mat_diffuse[] = {1.0,0.6,0.0,1.0};
GLfloat mat_specular[] = {1.0,1.0,1.0,1.0};
 
GLfloat light_ambient[] = {0.1,0.1,0.1,1.0};
//GLfloat light_diffuse[] = {1.0,1.0,1.0,0.0};
GLfloat light_diffuse[] = {0.2,1.0,0.2,0.0};
GLfloat light_specular[] = {1.0,1.0,1.0,0.0};
GLfloat light_position[] = {2.0,23.0,-4.0,1.0};
 
void myInit(void)
{
 glClearColor(0.0,0.0,0.0,0.0);//設定背景色
 
 /*為光照模型指定材質引數*/
 glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient);
 glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);
 glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
 glMaterialf(GL_FRONT,GL_SHININESS,60.0);
 
 /*設定光源引數*/
 glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient);
 glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse);
 glLightfv(GL_LIGHT0,GL_SPECULAR,light_specular);
 glLightfv(GL_LIGHT0,GL_POSITION,light_position);
 
 glEnable(GL_LIGHTING);
 glEnable(GL_LIGHT0);
 
 /*enable depth comparisons and update the depth buffer*/
 glEnable(GL_DEPTH_TEST);
 /*設定特殊效果*/
 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
 glHint(GL_LINE_SMOOTH_HINT,GL_DONT_CARE);
 glEnable(GL_BLEND);
 
 glEnable(GL_AUTO_NORMAL);
 glEnable(GL_NORMALIZE);
 glFrontFace(GL_CW);
 glShadeModel(GL_SMOOTH);
 glEnable(GL_LINE_SMOOTH);
 
}
 
void myDisplay(void)
{
 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
 glColor3f(0.4,0.4,0.4);
 glTranslatef(0.0,-1.0,0.0);
 glRotatef(50.0,1.0,0.0,0.0);
 glPushMatrix();
 /*繪製曲面*/
 glEnable(GL_MAP2_VERTEX_3);
 glMap2f(GL_MAP2_VERTEX_3,0,1,3,5,0,1,15,5,&ctrlpoints[0][0][0]);
 glMapGrid2f(10.0,0.0,1.0,10.0,0.0,1.0);
 glEvalMesh2(GL_FILL,0,10.0,0,10.0);
 glPopMatrix();
 glutSwapBuffers();
}
 
void myReshape(GLsizei w,GLsizei h)
{
 glViewport(0,0,w,h);
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 gluPerspective(60.0,(GLfloat)w/(GLfloat)h,1.0,100.0);
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();
 glTranslatef(0.0,0.0,-5.0);
}
 
int main(int argc,char ** argv)
{
 /*初始化*/
 glutInit(&argc,argv);
 glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
 glutInitWindowSize(400,400);
 glutInitWindowPosition(200,200);
 
 /*建立視窗*/
 glutCreateWindow("lighted Bezier surface");
 
 /*繪製與顯示*/
 myInit();
 glutReshapeFunc(myReshape);
 glutDisplayFunc(myDisplay);
 
 /*進入GLUT事件處理迴圈*/
 glutMainLoop();
 return(0);
}

void glMap2f(GLenum target,GLfloat u1,GLfloat u2,Glint ustride, Glint uorder, GLfloat v1, GLfloat v2, Glint vstride, Glint vorder, const GLfloat *points);
定義2維求值器。
  target指定求值器生成的數值型別。本例中的GL_MAP2_VERTEX_3 指明每一個控制點為x、y、z表示的三個浮點值。
  u1,u2指定線性對映。
  ustride 指定控制點Rij的起始點和控制點 R(i+1)j的的起始點之間單精度或雙精度浮點值的個數。這裡i和j分別是u和v控制點索引,它允許控制點裝入任意的資料結構中。唯一的限制是對於特定控制點的數值必須存在連續的記憶體單元。
  uorder控制點陣列在u軸方向上的維數。
  v1,v2指定線性對映v
  vstride指定控制點Rij的起始點和控制點 Ri(j+ 1)的起始點之間單精度或雙精度浮點值的個數。這裡i和j分別是u和v控制點索引,它允許控制點裝入任意的資料結構中。唯一的限制是對於特定控制點的數值必須存在連續的記憶體單元。
  vorder控制點陣列在v軸方向上的維數。
  points 一個指向控制點陣列的指標。


glMapGrid定義一維或二維網格。
void glMapGrid2f(Glint un, GLfloat u1, GLfloat u2,Glint vn, GLfloat v1,GLfloat v2);
  un 在網格[u1,u2]中的分段數目。
  u1,u2 指定整數網格範圍 i= 0;i= un的對映。
  vn在網格[v1,v2]中的分段數目。
  v1,v2 指定整數網格範圍 j = 0;j= vn的對映。


glEvalMesh 計算一維或二維點或線網格。
void glEvalMesh2(GLenum mode,Glint i1,Glint i2,Glint j1,Glint j2);
  mode 指定是否計算二維點、線或多邊形的網格。
  i1,i2 分別為網格定義域變數i的第一個和最後一個整數值。
  j1,j2分別為網格定義域變數j的第一個和最後一個整數值。
  glMapGrid和glEvalMesh用來生成並求取一系列等間隔的網格點,glEvalMesh逐步計算一維或二維網格,他的定義範圍由glMap指定。mode決定最終計算的頂點是繪製為點、線還是充實的多邊形。

以下分別是兩組不同控制點的效果;控制點座標在程式碼中;


二 opengl繪製Bezier Curve

#include "gl/glut.h"    
    
int Line_Count = 80;     
// 線條數越大 曲面越平滑     
// 線條數越小 曲面越粗糙     
// 可以從 左下 右下 兩條曲線得到對比    
    
// 左上曲線控制點    
GLfloat ControlPoints0[4][3] =     
{    
    { -4.0 ,  1.0 , 0.0 } , // 控制點在陣列中的順序決定曲線樣式    
    { -1.0 ,  1.0 , 0.0 } ,    
    { -1.0 ,  4.0 , 0.0 } ,     
    { -4.0 ,  4.0 , 0.0 }       
};    
    
// 右上曲線控制點    
GLfloat ControlPoints1[4][3] =     
{    
    {  4.0 ,  1.0 , 0.0 } ,     
    {  1.0 ,  4.0 , 0.0 } ,     
    {  1.0 ,  1.0 , 0.0 } ,     
    {  4.0 ,  4.0 , 0.0 }       
};    
    
// 右下曲線控制點    
GLfloat ControlPoints2[4][3] =     
{    
    {  1.0 , -4.0 , 0.0 } ,    
    {  4.0 , -4.0 , 0.0 } ,     
    {  1.0 , -1.0 , 0.0 } ,    
    {  4.0 , -1.0 , 0.0 }    
};    
    
// 左下曲線控制點    
GLfloat ControlPoints3[4][3] =     
{    
    { -4.0 , -4.0 , 0.0 } ,    
    { -1.0 , -4.0 , 0.0 } ,     
    { -4.0 , -1.0 , 0.0 } ,    
    { -1.0 , -1.0 , 0.0 }    
};    
    
void Display( void )    
{    
    int i;    
    
    glClear( GL_COLOR_BUFFER_BIT );    
    glLoadIdentity();    
    
    // 先繪製控制點 再繪製曲線    
    // 左上曲線    
    glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ControlPoints0[0][0]);     
    glColor3f( 0 , 0 , 1.0 );    
    glBegin( GL_POINTS );    
        for( i = 0 ; i < 4 ; i++ )     
        {    
            glVertex3fv( ControlPoints0[i] );    
        }    
    glEnd();    
    
    glColor3f(0.0, 1.0, 0.0);    
    glBegin( GL_LINE_STRIP );    
        for( i = 0 ; i <= Line_Count ; i++ )     
        {    
            glEvalCoord1f( (GLfloat)i/Line_Count );    
        }      
    glEnd();    
    
    // 右上曲線    
    glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ControlPoints1[0][0]);    
    glColor3f( 1.0 , 0.0 , 0.0 );    
    glBegin( GL_POINTS );    
        for( i = 0 ; i < 4 ; i++ )     
        {    
            glVertex3fv( ControlPoints1[i] );    
        }    
    glEnd();    
    
    glColor3f(0.0, 1.0, 0.0);    
    glBegin( GL_LINE_STRIP );    
        for( i = 0 ; i <= Line_Count ; i++ )     
        {    
            glEvalCoord1f( (GLfloat)i/Line_Count );    
        }      
    glEnd();    
    
    // 右下曲線    
    glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ControlPoints2[0][0]);    
    glColor3f( 0.0 , 0.0 , 1.0 );    
    glBegin( GL_POINTS );    
        for( i = 0 ; i < 4 ; i++ )     
        {    
            glVertex3fv( ControlPoints2[i] );    
        }    
    glEnd();    
    
    glColor3f(0.0, 1.0, 0.0);    
    glBegin( GL_LINE_STRIP );    
        for( i = 0 ; i <= Line_Count ; i++ )     
        {    
            glEvalCoord1f( (GLfloat)i/Line_Count );    
        }      
    glEnd();    
    
    // 左下曲線    
    Line_Count = 8; // 降低線條數 曲線變粗糙    
    glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ControlPoints3[0][0]);    
    glColor3f( 1.0 , 1.0 , 0.0 );    
    glBegin( GL_POINTS );    
        for( i = 0 ; i < 4 ; i++ )     
        {    
            glVertex3fv( ControlPoints3[i] );    
        }    
    glEnd();    
    
    glColor3f(0.0, 1.0, 0.0);    
    glBegin( GL_LINE_STRIP );    
        for( i = 0 ; i <= Line_Count ; i++ )     
        {    
            glEvalCoord1f( (GLfloat)i/Line_Count );    
        }      
    glEnd();    
    
    glFlush();    
}    
    
void Initialize()    
{    
    glClearColor( 0.0 , 0.0 , 0.0 , 0.0 );    
    glShadeModel( GL_SMOOTH );    
    glEnable(GL_MAP1_VERTEX_3);    
    glEnable( GL_LINE_SMOOTH ); // 平滑線條    
    glPointSize( 6.0 ); // 把點變大一點 看的清楚    
}    
    
void Reshape( int Width , int Height )    
{    
    glViewport( 0 , 0 , (GLsizei)Width , (GLsizei)Height );    
    
    glMatrixMode( GL_PROJECTION );    
    glLoadIdentity();    
    
    if( Width <= Height )    
    {    
        glOrtho( -5.0 , 5.0 , -5.0 * (GLfloat)Height / (GLfloat)Width , 5.0 * (GLfloat)Height / (GLfloat)Width , -5.0 , 5.0 );    
    }    
    
    else    
    {    
        glOrtho( -5.0 * (GLfloat)Width / (GLfloat)Height , 5.0 * (GLfloat)Width / (GLfloat)Height , -5.0 , 5.0 , -5.0 , 5.0 );    
    }    
    
    glMatrixMode( GL_MODELVIEW );    
    glLoadIdentity();    
}    
    
void main()    
{    
    glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB );    
    glutInitWindowSize( 700 , 700 );    
    glutInitWindowPosition( 162 , 34 );    
    glutCreateWindow( "Bezier Curve" );    
    Initialize();    
    glutDisplayFunc( Display );    
    glutReshapeFunc( Reshape );    
    glutMainLoop();    

轉:https://blog.csdn.net/bcbobo21cn/article/details/51073246