歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

OpenGL超級寶典學習筆記——畫三角形

學習了畫線的知識,我們可以使用GL_LINE_LOOP來畫閉合的多邊形。但是使用這種方式畫出來的只有線框,多邊形沒有填充顏色。OpenGL支持繪制實心的多邊形,並使用當前的顏色進行填充。

 

三角形

簡單的三角形,需要指定三個頂點。

   1: glBegin(GL_TRIANGLES);
   2:     glVertex2f(0.0f, 0.0f);            // V0
   3:     glVertex2f(25.0f, 25.0f);          // V1
   4:     glVertex2f(50.0f, 0.0f);           // V2
   5:     glVertex2f(-50.0f, 0.0f);          // V3
   6:     glVertex2f(-75.0f, 50.0f);         // V4
   7:     glVertex2f(-25.0f, 0.0f);          // V5
   8: glEnd();
   9: 

這兩個三角形會使用當前的顏色進行填充。

 

多邊形的環繞

按照頂點指定的順序和方向組合稱為環繞。上圖的兩個多邊形是順時針環繞的。我們可以通過改變頂點的順序,從而改變環繞方向。我們把v4和v5的順序調換過來,則這個三角形的環繞方向為逆時針了。

OpenGL默認是逆時針環繞方向為正方向,即逆時針環繞的三角形為正面。上圖左邊的三角形,顯示的是正面,而右邊的顯示的是反面。我們也可以通過函數glFrontFace(GL_CW);來告訴OpenGL順時針環繞的多邊形是正面。環繞方向是多邊形一個非常有用的性質,可以用於消除不必要的面。

 

三角形帶

我們可以繪制多個三角形連起來形成多個面或者多邊形。使用GL_TRIANGLE_STRIP圖元,可以繪制一串相連的多邊形,來節省大量的時間。

由上圖可以看到,多邊形的邊的繪制順序並不是完全按照我們指定的頂點順序的。而是按照OpenGL指定的順序逆時針方向繪制的。

使用三角形帶而不是分別指定每個三角形的頂點的優勢有兩個:

  1. 用前面三個頂點指定一個三角形後,只需再指定一個頂點就能畫出第二個三角形。要繪制大量的三角形時,這種方法可以節省大量的代碼以及數據存儲空間
  2. 運算性能的提高和帶寬的節省。更少的頂點,從內存傳輸的顯卡的時間更快,以及參與變換的頂點更少。

 

三角形扇

除了三角形帶之外,我們還可以通過GL_TRIANGLE_FAN圖元,創建一組圍繞一個中心點的三角形扇。通過制定5個頂點我們就可以繪制3個三角形來形成三角形扇。用3個頂點指定一個三角形後,後續的頂點Vn與原點V0以及前面的一個頂點Vn-1形成一個三角形。

 

創建實心物體

 


   1: static void RenderScene()
   2: {
   3:   //清除顏色緩沖區和深度緩沖區
   4:     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   5: 
   6:     GLfloat x, y, z, angle;
   7:   //用於顏色判斷
   8:   bool color;
   9:     glColor3f(1.0f, 1.0f, 0.0f);
  10:   //是否開啟深度緩沖
  11:   if (bDepth)
  12:   {
  13:     glEnable(GL_DEPTH_TEST);
  14:   }
  15:   else
  16:   {
  17:     glDisable(GL_DEPTH_TEST);
  18:   }
  19:   //是否開啟隱藏面消除
  20:   if (bCull)
  21:   {
  22:     glEnable(GL_CULL_FACE);
  23:   }
  24:   else
  25:   {
  26:     glDisable(GL_CULL_FACE);
  27:   }
  28:   //開啟線框模式 
  29:   if (bOutLine)
  30:   {
  31:     glPolygonMode(GL_BACK, GL_LINE) ;
  32:   }
  33:   else
  34:   {
  35:     glPolygonMode(GL_BACK, GL_FILL);
  36:   }
  37:
  38: 
  39:   glPushMatrix();
  40:   glRotatef(xRot, 1.0f, 0.0f, 0.0f);
  41:   glRotatef(yRot, 0.0f, 1.0f, 0.0f);
  42:   //畫椎體
  43:   glBegin(GL_TRIANGLE_FAN);
  44:     glVertex3f(0.0f, 0.0f, 70.0f);
  45: 
  46:     for (angle = 0.0f; angle <= (2 * GL_PI); angle += (GL_PI  / 8))
  47:     {
  48:           x = 50.0f * sin(angle);
  49:           y = 50.0f * cos(angle);
  50:           color = !color;
  51:
  52:       glVertex3f(x, y, 0.0f);
  53:           if(color)
  54:               glColor3f(1.0f, 0.0f, 0.0f);
  55:           else
  56:               glColor3f(0.0f, 1.0f, 1.0f);
  57:     }
  58:   glEnd();
  59:   //畫椎體的底面
  60:     glBegin(GL_TRIANGLE_FAN);
  61:       glVertex2f(0.0f, 0.0f);
  62: 
  63:       for (angle = 0.0f; angle <= (2 * GL_PI); angle += (GL_PI  / 8))
  64:       {
  65:           x = 50.0f * sin(angle);
  66:           y = 50.0f * cos(angle);
  67:           color = !color;
  68:
  69:           glVertex2f(x, y);
  70: 
  71:           if(color)
  72:               glColor3f(1.0f, 0.0f, 0.0f);
  73:           else
  74:               glColor3f(0.0f, 1.0f, 1.0f);
  75:       }
  76:     glEnd();
  77: 
  78:   glPopMatrix();
  79:     glutSwapBuffers();
  80: }
  81: 
  82: static void SetupRC()
  83: {
  84:     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  85:   //設置環繞方向
  86:     glEnable(GL_CW);
  87:   //設置填充模式
  88:     glShadeModel(GL_FLAT);
  89:   //設置要消除的隱藏面,這裡設置為反面
  90:   glCullFace(GL_BACK);
  91: }

 

使用紅青相間的方式來繪制一個錐體。

 

設置多邊形的顏色

多邊形的填充模式有兩種一種是單調著色GL_FLAT,一種平滑著色GL_SMOOTH。

通過glShadeMode(GL_FLAT);和glShadeMode(GL_SMOOTH);來設置。單調著色以三角形的最後一個頂點的顏色來填充三角形。平滑著色則是用三個頂點的顏色值進行內插值運算,來填充三角形的顏色。

平滑著色效果如下:

 

隱藏面消除

如果沒有使用深度緩沖區,來進行深度測試。上面的椎體如何旋轉(通過方向鍵可以旋轉),都是把底面顯示了出來。因為底面我們是在後面畫的,最後一個繪制的物體出現在之前繪制的物體的前面。如果開啟了深度測試來解決問題。

深度測試:當一個像素被繪制時,它將被設置一個值(z值),以表示它和觀測者的距離。以後當這個位置要繪制新像素時,新像素的z值就會和舊像素的z值進行比較。如果新像素z值更高,則更靠近觀察者,則應該被繪制,反之被忽略。

啟用深度測試只須調用glEnable(GL_DEPTH_TEST);每次場景被渲染之前,應該清楚深度緩沖區,與清楚顏色緩沖區類似。

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

在程序用使用右鍵點擊,彈出菜單,深度測試來切換深度測試。在繪制3D實體時,深度測試往往是必須的。

 

剔除

 

雖然啟用深度測試,可以消除隱藏面。但很多時候,我們清楚那些面是不需要繪制,應該被剔除的。例如:多邊形的背面不應該被顯示。如果我們告知OpenGL這個圖形面不需要被繪制,就不會把這個圖形發送給OpenGL驅動程序和硬件,可以提高性能。

啟用剔除面的功能。

//指定順時針環繞的面為正面

glFrontFace(GL_CW);

//開啟剔除面,剔除背面。

glEnable(GL_CULL_FACE);

錐體的底面面向錐體內部的是正面。要改變底面的正面,可以再繪制底面時設置glFrontFace(GL_CCW);

 

多邊形模式

多邊形我們可以指定它的模式,要填充還是只畫線框或者只畫頂點。

通過glPolygonMode(GL_BACK, GL_LINE) ;設置多邊形的背面只畫線。

通過glPolygonMode(GL_BACK, GL_FILL) ;設置多邊形的背面為實體。

 

通過glPolygonMode(GL_BACK, GL_POINT) ;設置多邊形的背面只畫點。

源代碼:https://github.com/sweetdark/openglex/tree/master/triangle

OpenGL超級寶典 第4版 中文版PDF+英文版+源代碼 見  http://www.linuxidc.com/Linux/2013-10/91413.htm

OpenGL編程指南(原書第7版)中文掃描版PDF 下載 http://www.linuxidc.com/Linux/2012-08/67925.htm

OpenGL 渲染篇 http://www.linuxidc.com/Linux/2011-10/45756.htm

Ubuntu 13.04 安裝 OpenGL http://www.linuxidc.com/Linux/2013-05/84815.htm

OpenGL三維球體數據生成與繪制【附源碼】 http://www.linuxidc.com/Linux/2013-04/83235.htm

Ubuntu下OpenGL編程基礎解析 http://www.linuxidc.com/Linux/2013-03/81675.htm

如何在Ubuntu使用eclipse for c++配置OpenGL http://www.linuxidc.com/Linux/2012-11/74191.htm 

更多《OpenGL超級寶典學習筆記》相關知識 見 http://www.linuxidc.com/search.aspx?where=nkey&keyword=34581

Copyright © Linux教程網 All Rights Reserved