OpenGL學習筆記(四):曲線曲面

來源:互聯網
上載者:User
文章目錄
  • 3.1 一維求值器
  • 3.2 一維均勻求值器
  • 3.3 二維求值器
  • 4.1 選擇渲染屬性
  • 4.2 建立並繪製曲線曲面

作者:yurunsun@gmail.com
新浪微博@孫雨潤 新浪部落格
CSDN部落格

日期: 2013-6-13

本章內容:

  1. 凹多邊形分格化
  2. 二次方程表面
  3. 求值器
  4. NURBS
1. 凹多邊形分格化

OpenGL顯示凹多邊形時必須先分解為簡單凸多邊形,這種劃分方法稱為多邊形分格化(tesselation),glu提供一組函數接受複雜多邊形輪廓線,返回一些三角形、三角形網、三角形扇以及直線的組合。

  1. 建立一個新的分格化對象

    GLUtesselator* gluNewTess(void);
  2. 註冊回呼函數

    void gluTessCallback(GLUtesselator *tessobj, GLenum type, void (*fn)());
  3. 指定分格化屬性,例如環繞規則來確定哪些地區填充、哪些不該著色

    void gluTessProperty(GLUtesselator *tessobj, GLenum property, GLdouble value);void gluTessNormal(GLUtesselator *tessobj, GLdouble x, GLdouble y, GLdouble z);
  4. 指定一個或多個閉合多邊形的輪廓線來渲染經過分格化的多邊形,最好將分格化後的多邊形放入顯示列表中

    void gluTessBeginPolygon(GLUtesselator *tessobj, void *user_data);void gluNextContour(GLUtriangulatorObj *tessobj, GLenum type);void gluTessEndPolygon(GLUtesselator *tessobj);void gluTessBeginContour(GLUtesselator *tessobj);void gluNextContour(GLUtriangulatorObj *tessobj, GLenum type);void gluTessEndContour(GLUtesselator *tessobj);void gluTessVertex(GLUtesselator *tessobj, GLdouble coords[3], void *vertex_data);
  5. 繼續使用此分格化對象,或者刪除

    void gluDeleteTess(GLUtesselator *tessobj);
2. 二次方程表面

使用glu建立和渲染二次方程表面步驟如下:

  1. gluNewQuadric()函數建立一個二次方程對象
  2. 指定這個二次方程對象的屬性
    • gluQuadricOrientation()函數控制環繞方向,區分內部外部地區
    • gluQuadricDrawStyle()函數選擇把物體渲染成點、直線、填充多邊形
    • gluQuadricNormal()函數為每個頂點或每個面指定一條法線
    • gluQuadricTexture()函數產生紋理座標
  3. gluQuadricCallback()函數註冊一個錯誤處理函數
  4. 根據需要調用相應二次方程表面渲染函數:

    gluSphere();gluCylinder();gluDisk();gluPartialDisk();
  5. gluDeleteQuadric()銷毀二次方程對象

3. 求值器3.1 一維求值器
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 init(void) {    glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]);    glEnable(GL_MAP1_VERTEX_3);}void display(void) {    glBegin(GL_LINE_STRIP);        for (int i = 0; i <= 30; i++)             glEvalCoord1f((GLfloat) i/30.0);    glEnd();}

使用下面函數定義一維求值器:

void glMap1f(GLenum target, float u1, float u2, GLint stride, GLint order, const float *points);GL_MAP1_VERTEX_3            //x, y, zvertex coordinatesGL_MAP1_VERTEX_4            //x, y, z, wvertex coordinatesGL_MAP1_INDEX               //color indexGL_MAP1_COLOR_4             //R, G, B, AGL_MAP1_NORMAL              //normal coordinatesGL_MAP1_TEXTURE_COORD_1     //stexture coordinatesGL_MAP1_TEXTURE_COORD_2     //s, ttexture coordinatesGL_MAP1_TEXTURE_COORD_3     //s, t, rtexture coordinatesGL_MAP1_TEXTURE_COORD_4     //s, t, r, qtexture coordinates
  • target: GLMAP1VERTEX_3表示指定了應用程式提供的三維控制點以及應該產生的三維頂點
  • u1: 0.0表示參數u的低值
  • u2: 1.0表示參數u的高值
  • stride: 3表示從一個控制點跳到下一個控制點時應該推進多少浮點值
  • order: 4表示樣條的階數
  • points: &ctrlpoints[0][0]表示指向第一個控制點的資料的指標

下面函數對已啟用的求值器執行計算:

void glEvalCoord1{fd}(TYPE u);void glEvalCoord1{fd}v(const TYPE *u);

可以一次使用多個求值器進行計算,即如果定義並啟用了GL_MAP1_VERTEX_3和一個GL_MAP1_COLOR_4,就可以調用`glEvalCoord1()函數同時產生一個位置和一種顏色。

3.2 一維均勻求值器

在上例中課件使用了i/30,即使u值均勻分布。更方便的方法是調用glMapGrid1f()函數定義一個一維網格,然後使用glEvalMesh1()函數應用這個網格。

void glMapGrid1{fd}(GLint n, TYPE u1, TYPE u2);void glEvalMesh1(GLenum mode, GLint p1, GLint p2);

第二個函數相當於

glBegin(GL_POINTS);    for (i = p1; i <= p2; i++)         glEvalCoord1(u1 + i*(u2-u1)/n);glEnd();
3.3 二維求值器

與一維求值器的區別就是需要考慮兩個參數u和v.

void glMap2{fd}(GLenum target, TYPE u1, TYPE u2, GLint ustride,                GLint uorder,TYPE v1, TYPE v2, GLint vstride,                GLint vorder, TYPE points);void glEvalCoord2{fd}(TYPE u, TYPE v);void glEvalCoord2{fd}v(const TYPE *values);

同樣有二維均勻求值器:

void glMapGrid2{fd}(GLint nu,TYPE u1, TYPE u2, GLint nv,TYPE v1, TYPE v2);void glEvalMesh2(GLenummode, GLint i1, GLint i2, GLint j1, GLint j2);
4. NURBS介面

GLU建立在OpenGL求值器函數的基礎上提供了NURBS介面。使用步驟如下:

  1. glEnable(GL_AUTO_NORMAL)自動產生法線(也可以自己計算)
  2. gluNewNurbsRENDERER()建立指向NURBS對象的指標
  3. gluNurbsProperty()選擇渲染屬性
  4. gluNurbsCallback()註冊錯誤回呼函數
  5. gluBeginCurve()/gluBeginSurface()聲明開始繪製曲線曲面
  6. gluNurbsCurve()/gluNurbsSurface()產生和渲染曲線曲面
  7. gluEndCurve()/gluEndSurface()聲明結束繪製曲線曲面

下面重點解釋其中幾個步驟:

4.1 選擇渲染屬性
voidgluNurbsProperty(GLUnurbsObj *nobj, GLenum property, GLfloat value);GLU_DISPLAY_MODE,               // GLU_FILL, GLU_OUTLINE_POLYGON, GLU_OUTLINE_PATCHGLU_NURBS_MODE,                 // GLU_NURBS_RENDERER, GL_NURBS_TESSELLATORGLU_CULLING,                    //GLU_SAMPLING_METHOD,            // GLU_PATH_LENTH, GLU_PARAMETRIC_ERROR, GLU_DOMAIN_DISTANCEGLU_SAMPLING_TOLERANCE,         GLU_PARAMETRIC_TOLERANCE, GLU_U_STEP, GLU_V_STEP, GLU_AUTO_LOAD_MATRIX            // 是否需要從openGL伺服器下載投影矩陣、模視矩陣和視口 否則使用:void gluLoadSamplingMatrices(GLUnurbsObj *nobj,        const GLfloat modelMatrix[16],         const GLfloat projMatrix[16],         const GLint viewport[4]);
4.2 建立並繪製曲線曲面
void gluNurbsSurface(GLUnurbsObj *nobj, GLint uknot_count,        GLfloat *uknot, GLint vknot_count, GLfloat *vknot,        GLint u_stride, GLint v_stride, GLfloat *ctlarray,        GLint uorder, GLint vorder, GLenum type);gluBeginSurface(nobj);    gluNurbsSurface(nobj, ..., GL_MAP2_TEXTURE_COORD_2);    gluNurbsSurface(nobj, ..., GL_MAP2_NORMAL);    gluNurbsSurface(nobj, ..., GL_MAP2_VERTEX_3);gluEndSurface(nobj);
  • 如果這篇文章對您有協助,請到CSDN部落格留言;
  • 轉載請註明:來自雨潤的技術部落格

    http://blog.csdn.net/sunyurun

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.