1. 程式人生 > >OpenGL基礎圖形程式設計

OpenGL基礎圖形程式設計

一、OpenGL與3D圖形世界

1.1、OpenGL使人們進入三維圖形世界

  我們生活在一個充滿三維物體的三維世界中,為了使計算機能精確地再現這些物體,我們必須能在三維空間描繪這些物體。我們又生活在一個充滿資訊的世界中,能否儘快地理解並運用這些資訊將直接影響事業的成敗,所以我們需要用一種最直接的形式來表示這些資訊。
  最近幾年計算機圖形學的發展使得三維表現技術得以形成,這些三維表現技術使我們能夠再現三維世界中的物體,能夠用三維形體來表示複雜的資訊,這種技術就是視覺化(Visualization)技術。視覺化技術使人能夠在三維圖形世界中直接對具有形體的資訊進行操作,和計算機直接交流。這種技術已經把人和機器的力量以一種直覺而自然的方式加以統一,這種革命性的變化無疑將極大地提高人們的工作效率。視覺化技術賦予人們一種模擬的、三維的並且具有實時互動的能力,這樣人們可以在三維圖形世界中用以前不可想象的手段來獲取資訊或發揮自己創造性的思維。機械工程師可以從二維平面圖中得以解放直接進入三維世界,從而很快得到自己設計的三維機械零件模型。醫生可以從病人的三維掃描圖象分析病人的病灶。軍事指揮員可以面對用三維圖形技術生成的戰場地形,指揮具有真實感的三維飛機、軍艦、坦克向目標開進並分析戰鬥方案的效果。
  更令人驚奇的是目前正在發展的虛擬現實技術,它能使人們進入一個三維的、多媒體的虛擬世界,人們可以遊歷遠古時代的城堡,也可以遨遊浩翰的太空。所有這些都依賴於計算機圖形學、計算機視覺化技術的發展。人們對計算機視覺化技術的研究已經歷了一個很長的歷程,而且形成了許多視覺化工具,其中SGI公司推出的GL三維圖形庫表現突出,易於使用而且功能強大。利用GL開發出來的三維應用軟體頗受許多專業技術人員的喜愛,這些三維應用軟體已涉及建築、產品設計、醫學、地球科學、流體力學等領域。隨著計算機技術的繼續發展,GL已經進一步發展成為OpenGL,OpenGL已被認為是高效能圖形和互動式視景處理的標準,目前包括ATT公司UNIX軟體實驗室、IBM公司、DEC公司、SUN公司、HP公司、Microsoft公司和 SGI公司在內的幾家在計算機市場佔領導地位的大公司都採用了OpenGL圖形標準。
  值得一提的是,由於Microsoft公司在 Windows NT中提供OpenGL圖形標準,OpenGL將在微機中廣泛應用,尤其是OpenGL三維圖形加速卡和微機圖形工作站的推出,人們可以在微機上實現三維圖形應用,如CAD設計、模擬模擬、三維遊戲等,從而更有機會、更方便地使用OpenGL及其應用軟體來建立自己的三維圖形世界。

1.2、OpenGL提供直觀的三維圖形開發環境


  OpenGL實際上是一種圖形與硬體的介面。它包括了120個圖形函式,開發者可以用這些函式來建立三維模型和進行三維實時互動。與其他圖形程式設計介面不同,OpenGL提供了十分清晰明瞭的圖形函式,因此初學的程式設計員也能利用OpenGL的圖形處理能力和1670萬種色彩的調色盤很快地設計出三維圖形以及三維互動軟體。
  OpenGL強有力的圖形函式不要求開發者把三維物體模型的資料寫成固定的資料格式,這樣開發者不但可以直接使用自己的資料,而且可以利用其他不同格式的資料來源。這種靈活性極大地節省了開發者的時間,提高了軟體開發效益。
  長期以來,從事三維圖形開發的技術人員都不得不在自己的程式中編寫矩陣變換、外部裝置訪問等函式,這樣為調製這些與自己的軟體開發目標關係並不十分密切的函式費腦筋,而OpenGL正是提供一種直觀的程式設計環境,它提供的一系列函式大大地簡化了三維圖形程式。例如:

  • OpenGL提供一系列的三維圖形單元供開發者呼叫。
  • OpenGL提供一系列的圖形變換函式。
  • OpenGL提供一系列的外部裝置訪問函式,使開發者可以方便地訪問滑鼠、鍵盤、空間球、資料手套等這種直觀的三維圖形開發環境體現了OpenGL的技術優勢,這也是許多三維圖形開發者熱衷於OpenGL的緣由所在。
1.3、OpenGL成為目前三維圖形開發標準
  OpenGL成為目前三維圖形開發標準在計算機發展初期,人們就開始從事計算機圖形的開發。直到計算機硬軟體和計算機圖形學高度發達的九十年代,人們發現複雜的資料以視覺的形式表現時是最易理解的,因而三維圖形得以迅猛發展,於是各種三維圖形工具軟體包相繼推出,如PHIGS、PEX、 RenderMan等。這些三維圖形工具軟體包有些側重於使用方便,有些側重於渲染效果或與應用軟體的連線,但沒有一種三維工具軟體包在互動式三維圖形建模能力、外部裝置管理以及程式設計方便程度上能夠OpenGL相比擬。
  OpenGL經過對GL的進一步發展,實現二維和三維的高階圖形技術,在效能上表現得異常優越,它包括建模、變換、光線處理、色彩處理、動畫以及更先進的能力,如紋理影射、物體運動模糊等。OpenGL的這些能力為實現逼真的三維渲染效果、建立互動的三維景觀提供了優秀的軟體工具。OpenGL在硬體、視窗、作業系統方面是相互獨立的。
  許多計算機公司已經把 OpenGL整合到各種視窗和作業系統中,其中作業系統包括UNIX、Windows NT、DOS等,視窗系統有X視窗、Windows等。為了實現一個完整功能的圖形處理系統,設計一個與OpenGL相關的系統結構為:其最底層是圖形硬體,第二層為作業系統,第三層為視窗系統,第四層為OpenGL,第五層為應用軟體。OpenGL是網路透明的,在客戶 — 伺服器(Client-Server
)體系結構中,OpenGL允許本地和遠端繪圖。所以在網路系統中,OpenGL在X視窗、Windows或其它視窗系統下都可以以一個獨立的圖形窗口出現。
  OpenGL作為一個性能優越的圖形應用程式設計介面(API)而適合於廣泛的計算環境,從個人計算機到工作站和超級計算機,OpenGL都能實現高效能的三維圖形功能。由於許多在計算機界具有領導地位的計算機公司紛紛採用OpenGL作為三維圖形應用程式設計介面,OpenGL應用程式具有廣泛的移植性。因此,OpenGL已成為目前的三維圖形開發標準,是從事三維圖形開發工作的技術人員所必須掌握的開發工具。




二、OpenGL概念建立
<>function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus(); 2.1、OpenGL基本理解
  OpenGL是一個與硬體圖形發生器的軟體介面,它包括了100多個圖形操作函式,開發者可以利用這些函式來構造景物模型、進行三維圖形互動軟體的開發。正如上一章所述,OpenGL是一個高效能的圖形開發軟體包。OpenGL支援網路,在網路系統中使用者可以在不同的圖形終端上執行程式顯示圖形。 OpenGL作為一個與硬體獨立的圖形介面,它不提供與硬體密切相關的裝置操作函式,同時,它也不提供描述類似於飛機、汽車、分子形狀等複雜形體的圖形操作函式。使用者必須從點、線、面等最基本的圖形單元開始構造自己的三維模型。當然,象OpenInventor那樣更高一級的基於OpenGL的三維圖形建模開發軟體包將提供方便的工具。因此OpenGL的圖形操作函式十分基本、靈活。例如OpenGL中的模型繪製過程就多種多樣,內容十分豐富,OpenGL提供了以下的對三維物體的繪製方式:
  • 網格線繪圖方式wireframe
    這種方式僅繪製三維物體的網格輪廓線。
  • 深度優先網格線繪圖方式depth_cued
    用網格線方式繪圖,增加模擬人眼看物體一樣,遠處的物體比近處的物體要暗些。
  • 反走樣網格線繪圖方式antialiased
    用網格線方式繪圖,繪圖時採用反走樣技術以減少圖形線條的參差不齊。
  • 平面消隱繪圖方式flat_shade
    對模型的隱藏面進行消隱,對模型的平面單元按光照程度進行著色但不進行光滑處理。
  • 光滑消隱繪圖方式smooth_shade
    對模型進行消隱按光照渲染著色的過程中再進行光滑處理,這種方式更接近於現實。
  • 加陰影和紋理的繪圖方式shadows、textures
    在模型表面貼上紋理甚至於加上光照陰影,使得三維景觀象照片一樣。
  • 運動模糊的繪圖方式motion-blured
    模擬物體運動時人眼觀察所感覺的動感現象。
  • 大氣環境效果atmosphere-effects
    在三維景觀中加入如霧等大氣環境效果,使人身臨其境。
  • 深度域效果depth-of-effects
    類似於照相機鏡頭效果,模型在聚焦點處清晰,反之則模糊。
  這些三維物體繪圖和特殊效果處理方式,說明OpenGL已經能夠模擬比較複雜的三維物體或自然景觀,這就是我們所面對的OpenGL。

2.2、OpenGL工作流程
  整個OpenGL的基本工作流程如下圖:

  其中幾何頂點資料包括模型的頂點集、線集、多邊形集,這些資料經過流程圖的上部,包括運算器、逐個頂點操作等;影象資料包括象素集、影像集、點陣圖集等,影象象素資料的處理方式與幾何頂點資料的處理方式是不同的,但它們都經過光柵化、逐個片元(Fragment)處理直至把最後的光柵資料寫入幀緩衝器。在OpenGL中的所有資料包括幾何頂點資料和象素資料都可以被儲存在顯示列表中或者立即可以得到處理。OpenGL中,顯示列表技術是一項重要的技術。
  OpenGL要求把所有的幾何圖形單元都用頂點來描述,這樣運算器和逐個頂點計算操作都可以針對每個頂點進行計算和操作,然後進行光柵化形成圖形碎片;對於象素資料,象素操作結果被儲存在紋理組裝用的記憶體中,再象幾何頂點操作一樣光柵化形成圖形片元。
  整個流程操作的最後,圖形片元都要進行一系列的逐個片元操作,這樣最後的象素值BZ送入幀緩衝器實現圖形的顯示。

2.3、OpenGL圖形操作步驟
  在上一節中說明了OpenGL的基本工作流程,根據這個流程可以歸納出在OpenGL中進行主要的圖形操作直至在計算機螢幕上渲染繪製出三維圖形景觀的基本步驟:
  1)根據基本圖形單元建立景物模型,並且對所建立的模型進行數學描述(OpenGL中把:點、線、多邊形、影象和點陣圖都作為基本圖形單元)。
  2)把景物模型放在三維空間中的合適的位置,並且設定視點(viewpoint)以觀察所感興趣的景觀。
  3)計算模型中所有物體的色彩,其中的色彩根據應用要求來確定,同時確定光照條件、紋理貼上方式等。
  4)把景物模型的數學描述及其色彩資訊轉換至計算機螢幕上的象素,這個過程也就是光柵化(rasterization)。
  在這些步驟的執行過程中,OpenGL可能執行其他的一些操作,例如自動消隱處理等。另外,景物光柵化之後被送入幀緩衝器之前還可以根據需要物件素資料進行操作。



三、WindowsNT下的OpenGL

3.1、Windows NT下的OpenGL函式
  如前面的章節所述,Windows NT下的OpenGL同樣包含100多個庫函式,這些函式都按一定的格式來命名,即每個函式都以gl開頭。Windows NT下的OpenGL除了具有基本的OpenGL函式外,還支援其他四類函式:
相應函式 具體說明
OpenGL實用庫 43個函式,每個函式以glu開頭。
OpenGL輔助庫 31個函式,每個函式以aux開頭。
Windows專用庫函式(WGL 6個函式,每個函式以wgl開頭。
Win32 API函式 5個函式,函式前面沒有專用字首。

  在OpenGL中有115個核心函式,這些函式是最基本的,它們可以在任何OpenGL的工作平臺上應用。這些函式用於建立各種各樣的形體,產生光照效果,進行反走樣以及進行紋理對映,進行投影變換等等。由於這些核心函式有許多種形式並能夠接受不同型別的引數,實際上這些函式可以派生出300 多個函式。
  OpenGL的實用函式是比OpenGL核心函式更高一層的函式,這些函式是通過呼叫核心函式來起作用的。這些函式提供了十分簡單的用法,從而減輕了開發者的程式設計負擔。OpenGL的實用函式包括紋理對映、座標變換、多邊形分化、繪製一些如橢球、圓柱、茶壺等簡單多邊形實體(本指南將詳細講述這些函式的具體用法)等。這部分函式象核心函式一樣在任何OpenGL平臺都可以應用。
  OpenGL的輔助庫是一些特殊的函式,這些函式本來是用於初學者做簡單的練習之用,因此這些函式不能在所有的OpenGL平臺上使用,在Windows NT環境下可以使用這些函式。這些函式使用簡單,它們可以用於視窗管理、輸入輸出處理以及繪製一些簡單的三維形體。為了使OpenGL的應用程式具有良好的移植性,在使用OpenGL輔助庫的時候應謹慎。
  6個WGL函式是用於連線OpenGL與Windows NT的,這些函式用於在Windows NT環境下的OpenGL視窗能夠進行渲染著色,在視窗內繪製點陣圖字型以及把文字放在視窗的某一位置等。這些函式把Windows與OpenGL揉合在一起。最後的5個Win32函式用於處理象素儲存格式和雙緩衝區,顯然這些函式僅僅能夠用於Win32系統而不能用於其它OpenGL平臺。

3.2、OpenGL基本功能
  OpenGL能夠對整個三維模型進行渲染著色,從而繪製出與客觀世界十分類似的三維景象。另外OpenGL還可以進行三維互動、動作模擬等。具體的功能主要有以下這些內容。
  • 模型繪製
    OpenGL能夠繪製點、線和多邊形。應用這些基本的形體,我們可以構造出幾乎所有的三維模型。OpenGL通常用模型的多邊形的頂點來描述三維模型。如何通過多邊形及其頂點來描述三維模型,在指南的在後續章節會有詳細的介紹。
  • 模型觀察
    在建立了三維景物模型後,就需要用OpenGL描述如何觀察所建立的三維模型。觀察三維模型是通過一系列的座標變換進行的。模型的座標變換在使觀察者能夠在視點位置觀察與視點相適應的三維模型景觀。在整個三維模型的觀察過程中,投影變換的型別決定觀察三維模型的觀察方式,不同的投影變換得到的三維模型的景象也是不同的。最後的視窗變換則對模型的景象進行裁剪縮放,即決定整個三維模型在螢幕上的圖象。
  • 顏色模式的指定
    OpenGL 應用了一些專門的函式來指定三維模型的顏色。程式設計師可以選擇二個顏色模式,即RGBA模式和顏色表模式。在RGBA模式中,顏色直接由RGB值來指定;在顏色表模式中,顏色值則由顏色表中的一個顏色索引值來指定。程式設計師還可以選擇平面著色和光滑著色二種著色方式對整個三維景觀進行著色。
  • 光照應用
    用OpenGL繪製的三維模型必須加上光照才能更加與客觀物體相似。OpenGL提供了管理四種光(輻射光、環境光、鏡面光和漫反射光)的方法,另外還可以指定模型表面的反射特性。
  • 圖象效果增強
    OpenGL提供了一系列的增強三維景觀的圖象效果的函式,這些函式通過反走樣、混合和霧化來增強圖象的效果。反走樣用於改善圖象中線段圖形的鋸齒而更平滑,混合用於處理模型的半透明效果,霧使得影像從視點到遠處逐漸褪色,更接近於真實。
  • 點陣圖和圖象處理
    OpenGL還提供了專門對點陣圖和圖象進行操作的函式。
  • 紋理對映
    三維景物因缺少景物的具體細節而顯得不夠真實,為了更加逼真地表現三維景物,OpenGL提供了紋理對映的功能。OpenGL提供的一系列紋理對映函式使得開發者可以十分方便地把真實圖象貼到景物的多邊形上,從而可以在視窗內繪製逼真的三維景觀。
  • 實時動畫
    為了獲得平滑的動畫效果,需要先在記憶體中生成下一幅圖象,然後把已經生成的圖象從記憶體拷貝到螢幕上,這就是OpenGL的雙快取技術(double buffer)。OpenGL提供了雙快取技術的一系列函式。
  • 互動技術
    目前有許多圖形應用需要人機互動,OpenGL提供了方便的三維圖形人機互動介面,使用者可以選擇修改三維景觀中的物體。
3.3、Windows NT下OpenGL的結構
  OpenGL的作用機制是客戶(client)/伺服器(sever)機制,即客戶(用OpenGL繪製景物的應用程式)向伺服器(即OpenGL核心)釋出OpenGL命令,伺服器則解釋這些命令。大多數情況下,客戶和伺服器在同一機器上執行。正是OpenGL的這種客戶/伺服器機制,OpenGL可以十分方便地在網路環境下使用。因此Windows NT下的OpenGL是網路透明的。正象Windows的圖形裝置介面(GDI)把圖形函式庫封裝在一個動態連結庫(Windows NT下的GDI32.DLL)內一樣,OpenGL圖形庫也被封裝在一個動態連結庫內(OPENGL32.DLL)。受客戶應用程式呼叫的OpenGL函式都先在OPENGL32.DLL中處理,然後傳給伺服器WINSRV.DLL。OpenGL的命令再次得到處理並且直接傳給Win32的裝置驅動介面(Device Drive Interface,DDI),這樣就把經過處理的圖形命令送給視訊顯示驅動程式。下圖簡要說明這個過程:
 
圖3-1 OpenGL在Windows NT下執行機制

  在三維圖形加速卡的GLINT圖形加速晶片的加速支援下,二個附加的驅動程式被加入這個過程中。一個OpenGL可安裝客戶驅動程式(Installable Client Driver,ICD)被加在客戶這一邊,一個硬體指定DDI(Hardware-specific DDI)被加在伺服器這邊,這個驅動程式與Wind32 DDI是同一級別的。


圖3-2 在三維圖形加速下OpenGL執行機制



四、OpenGL基礎程式結構

  用OpenGL編寫的程式結構類似於用其他語言編寫的程式。實際上,OpenGL是一個豐富的三維圖形函式庫,編寫OpenGL程式並非難事,只需在基本C語言中呼叫這些函式,用法同Turbo C、Microsoft C等類似,但也有許多不同之處。
  本指南所有的程式都是在Windows NT的Microsoft Visual C++整合環境下編譯連線的,其中有部分標頭檔案和函式是為這個環境所用的,例如判別作業系統的標頭檔案“glos.h”。此外,為便於各類讀者同時快速入門,在短時間內掌握OpenGL程式設計的基本方法和技巧,指南中例子儘量採用標準ANSI C呼叫OpenGL函式來編寫,而且所有例程都只採用OpenGL附帶的輔助庫中的視窗系統。此外,這樣也便於程式在各平臺間移植,尤其往工作站UNIX 作業系統移植時,也只需改動標頭檔案等很少很少的部分。下面列出一個簡單的OpenGL程式:

例4-1 OpenGL簡單例程Simple.c

#include <GL/gl.h>
  #include <GL/glaux.h>
  #include "glos.h"

  void main(void)
  {
    auxInitDisplayMode(AUX_SINGLE|AUX_RGBA);
    auxInitPosition(0,0,500,500);
    auxInitWindow("simple");

    glClearColor(0.0,0.0,0.0,0.0);
    glClear(GL_COLOR_BUFFER_BIT);

     glColor3f(1.0,0.0,0.0);
    glRectf(-0.5,-0.5,0.5,0.5);

     glFlush();
    _sleep(1000);
  }

  這個程式執行結果是在螢幕視窗內畫一個紅色的方塊。
  下面具體分析整個程式結構:首先,在程式最開始處是OpenGL標頭檔案:<GL/gl.h>、<GL/glaux.h>。前一個是gl庫的標頭檔案,後一個是輔助庫的標頭檔案。此外,在以後的幾章中還將說明OpenGL的另外兩個標頭檔案,一個是<GL/glu.h>實用庫的標頭檔案,另一個是<GL/glx.h>X視窗擴充庫的標頭檔案(這個常用在工作站上)。接下來是主函式main()的定義:一般的程式結構是先定義一個視窗:

auxInitDisplayMode(AUX_SINGLE|AUX_RGBA);
  auxInitPosition(0,0,500,500);
  auxInitWindow("simple");

  auxInitDisplayMode(AUX_SINGLE|AUX_RGBA)設定視窗顯示模式為RGBA方式,即彩色方式,並且圖形快取為單快取(SINGLE BUFFER)。 auxInitPosition(0, 0, 500, 500)定義視窗的初始位置,前兩個引數(0, 0)為視窗的左上角點的螢幕座標,後兩個引數(500,500)為視窗的寬度和高度。auxInitWindow("simple")是視窗初始化,字元引數是視窗名稱。
  然後是視窗內清屏:

glClearColor(0.0,0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT);

  第一句將視窗清為黑色,第二句將顏色緩衝區清為glClearColor(0.0, 0.0, 0.0, 0.0)命令所設定的顏色,即同窗口背景顏色一致。
  再接著是在視窗內畫一個物體:

glColor3f(1.0,0.0,0.0);
  glRectf(-0.5,-0.5,0.5,0.5);

  很明顯,第一句設定物體顏色,函式中前三個引數分別為R、G、B值,最後一個引數是Alpha值,範圍都從0至1;第二句繪製一個二維矩形。注意:OpenGL是針對三維圖形而言,因此用作OpenGL程式設計繪製物體必須意識到任何一個物體都是三維的,具有空間性,而顯示於螢幕上的物體都是三維物體在二維平面上的投影。
  從表面上看,上述程式程式碼很簡單,實際上已經用到了預設的投影形式(正射投影)。再看glFlush()函式,表示強制繪圖完成。最後一句_sleep(1000),引數單位為毫秒,整句意思是保持現有狀況一秒鐘,然後結束程式執行。這個函式是VC++的庫函式。
  總而言之,OpenGL程式基本結構為定義視窗、清理視窗、繪製物體、結束執行。 



五、OpenGL的資料型別和函式名

OpenGL的資料型別定義可以與其它語言一致,但建議在ANSI C下最好使用以下定義的資料型別,例如GLint、GLfloat等。具體型別見表5-1。
字首    資料型別                    相應C語言型別        OpenGL型別 
================================================================
b       8-bit integer            signed char         GLbyte 
s       16-bit integer           short               GLshort 
i       32-bit integer           long                        GLint,GLsizei 
f       32-bit floating-point    float                       GLfloat,GLclampf 
d       64-bit floating-point    double                      GLdouble,GLclampd 
ub      8-bit unsigned integer   unsigned char               GLubyte,GLboolean 
us      16-bit unsigned integer  unsigned short      GLushort 
ui      32-bit unsigned integer  unsigned long       GLuint,GLenum,GLbitfield 
表5-1 命令字首和引數資料型別

  OpenGL的庫函式命名方式很有規律,瞭解這種規律後閱讀和編寫程式都比較容易方便。
  首先,每個庫函式有字首gl、glu、glx或aux,表示此函式分屬於基本庫、實用庫、X視窗擴充庫或輔助庫,其後的函式名頭字母大寫,字尾是引數型別的簡寫,取i、f,參見表5-1。例:

  
glVertex2i(2,4);
  glVertex3f(2.0,4.0,5.0);

  注意:有的函式引數型別字尾前帶有數字2、3、4。2代表二維,3代表三維,4代表alpha值(以後介紹)。
  有些OpenGL函式最後帶一個字母v,表示函式引數可用一個指標指向一個向量(或陣列)來替代一系列單個引數值。下面兩種格式都表示設定當前顏色為紅色,二者等價。

glColor3f(1.0,0.0,0.0);
  float color_array[]={1.0,0.0,0.0};
  glColor3fv(color_array);

  除了以上基本命名方式外,還有一種帶“*”星號的表示方法,例如glColor*(),它表示可以用函式的各種方式來設定當前顏色。同理,glVertex*v()表示用一個指標指向所有型別的向量來定義一系列頂點座標值。
  最後,OpenGL也定義GLvoid型別,如果用C語言編寫,可以用它替代void型別。



六、OpenGL輔組庫的基本使用

  OpenGL是一個開放的系統,它是獨立於任何視窗系統或作業系統的。儘管它包含了許多圖形函式,但它卻沒有視窗函式,也沒有從鍵盤和滑鼠讀取事件的函式,所以要初學者寫出一個完整的圖形程式是相當困難的。另外,OpenGL圖形函式中只提供基本的幾何原形:點、線、多邊形,因此要建立基本的三維幾何體如球、錐體等,也很不容易。而OpenGL輔助庫就是為解決這些基本問題專門設計的,它提供了一些基本的視窗管理函式和三維圖形繪製函式,能幫助初學者儘快進入OpenGL世界,掌握關鍵的三維圖形技術,體會其中奇妙的樂趣。但是,對於複雜的應用,這些函式遠遠不夠,只能作為參考。

6.1、輔助庫函式分類
  這一節內容可以作為手冊查閱,初學者不必深究。
  輔助庫函式大致分為六類:

6.1.1 視窗初始化和退出
  相關函式有三個,它們在第一章已提到,這裡將詳細介紹:

void auxInitWindow(GLbyte *titleString)

  開啟一個由auxInitDisplayMode()和auxInitPosition()指定的視窗。函式引數是視窗標題,視窗背景預設顏色是RGBA下的黑色或顏色表(color_index)下的0號調色盤的顏色。按下Escape鍵可以完成關掉視窗、結束程式、全部清屏三項功能。

void auxInitDisplayMode(GLbitfield mask)

  設定視窗顯示模式。基本模式有RGBA或顏色表、單或雙快取,也可指定其他附加模式:深度、模板或累積快取(depth,stencil,and/or accumulation buffer)。引數mask是一組位標誌的聯合(取或),AUX_RGBA或AUX_INDEX、AUX_SINGLE或AUX_DOUBLE,以及其它有效標誌AUX_DEPTH、AUX_STENCIL或AUX_ACCUM。

void auxInitPosition(GLint x,GLint y,GLsizei width,GLsizei height)

  設定視窗位置及大小。引數(x, y)為視窗的左上角點的螢幕座標,引數(width, height)為視窗的寬度和高度,單位為象素,預設值為(0, 0, 100, 100)。

6.1.2 視窗處理和事件輸入
  當視窗建立後,且在進入主函式迴圈之前,應當登記以下列出的回撥函式(callback function):

void auxReshapeFunc(void(*function)(GLsizei,GLsizei))

  定義視窗改變時形狀重定函式。引數function是一個函式指標,這個函式帶有兩個引數,即視窗改變後的新寬度和新高度。通常,function是 glViewport(),顯示裁減後的新尺寸,重定義投影矩陣,以便使投影后影象的比例與視點匹配,避免比例失調。若不呼叫 auxReshapeFunc(),預設重定物體形狀的函式功能是呼叫一個二維的正射投影矩陣。運用輔助庫,視窗將在每個事件改變後自動重新繪製。

void auxKeyFunction(GLint key,void(*function)(void))

  定義鍵盤響應函式。引數function就是當按下key鍵時所呼叫的函式指標,輔助庫為引數key定義了幾個常量:AUX_0至AUX_9、 AUX_A至AUX_Z、AUX_a至AUX_z、AUX_LEFT、AUX_RIGHT、AUX_UP、AUX_DOWN(方向鍵)、 AUX_ESCAPE、AUX_SPACE或AUX_RETURN。

void auxMouseFunc(GLint button,Glint mode,void(*function)(AUX_EVENTREC *))

  定義滑鼠響應函式。引數function就是當滑鼠以mode方式作用於button時所呼叫的函式。引數button有 AUX_LEFTBUTTON、AUX_MIDDLEBUTTON或AUX_RIGHTBUTTON(以右手為標準)。引數mode代表滑鼠觸擊狀態,擊中時為AUX_MOUSEDOWN,釋放時為AUX_MOUSEUP。引數function必須帶一個引數,它是指向結構AUX_EVENNTREC的指標。當函式auxMouseFunc()被呼叫時將為這個結構分配相應的記憶體。通常用法類似如下:

void function(AUX_EVENTREC *event)
  {
    GLint x,y;
    x=event->data[AUX_MOUSEX];
    y=event->data[AUX_MOUSEY];
    ...
  }

6.1.3 顏色表裝入
  因為OpenGL本身沒有視窗系統,所以依賴於視窗系統的顏色對映就沒法裝入顏色查詢表。如果採用顏色表模式,就要用到輔助庫提供的用RGB值定義的單個顏色索引函式:

void auxSetOneColor(GLint index,GLfloat red,GLfloat green,GLfloat blue)

  設定自定義顏色的索引。引數index即索引號,引數red、green、blue分別為紅、綠、藍值,範圍在(0~1)內。

6.1.4 三維物體繪製
  每組三維物體包括兩種形式:網狀體(wire)和實心體(solid)。網狀體沒有平面法向,而實心體有,能進行光影計算,有光照時採用實心體模型。下面這些函式的 引數都是定義物體大小的,可以改變。

功能 函式
繪製球 void auxWireSphere(GLdouble radius)
void auxSolidSphere(GLdouble radius)
繪製立方體 void auxWireCube(GLdouble size)
void auxSolidCube(GLdouble size)
繪製長方體 void auxWireBox(GLdouble width,GLdouble height,GLdouble depth)
void auxSolidBox(GLdouble width,GLdouble height,GLdouble depth)
繪製環形圓紋面 void auxWireTorus(GLdouble innerRadius,GLdouble outerRadius)
void auxSolidTorus(GLdouble innerRadius,GLdouble outerRadius)
繪製圓柱 void auxWireCylinder(GLdouble radius,GLdouble height)
void auxSolidCylinder(GLdouble radius,GLdouble height)
繪製二十面體 void auxWireIcosahedron(GLdouble radius)
void auxSolidIcosahedron(GLdouble radius)
繪製八面體 void auxWireOctahedron(GLdouble radius)
void auxSolidOctahedron(GLdouble radius)
繪製四面體 void auxWireTetrahedron(GLdouble radius)
void auxSolidTetrahedron(GLdouble radius)
繪製十二面體 void auxWireDodecahedron(GLdouble radius)
void auxSolidDodecahedron(GLdouble radius)
繪製圓錐 void auxWireCone(GLdouble radius,GLdouble height)
void auxSolidCone(GLdouble radius,GLdouble height)
繪製茶壺 void auxWireTeapot(GLdouble size)
void aucSolidTeapot(GLdouble size)
表6-1

  以上物體均以各自中心為原點繪製,所有座標都已單位化,可以縮放。

6.1.5 背景過程管理

void auxIdleFunc(void *func)

  定義空閒狀態執行函式。引數func是一個指標,指向所要執行的函式功能。當它為零時,func執行無效。

6.1.6 程式執行

void auxMainLoop(void(*displayFunc)(void))

  定義場景繪製迴圈函式。displayFunc指標指向場景繪製函式。當視窗需要更新或場景發生改變時,程式便呼叫它所指的函式,重新繪製場景。

6.2、輔助庫應用示例
  下面舉一個輔助庫的應用例子,testaux.c:

例6-1 輔助庫應用例程 testaux.c

#include "glos.h"
  #include <GL/gl.h>
  #include <GL/glaux.h>

  void myinit(void);
  void CALLBACK myReshape(GLsizei w,GLsizei h);
  void CALLBACK display(void);

  void myinit(void)
  {
    glClearColor(0.0,0.0,0.0,0.0);
    glClear(GL_COLOR_BUFFER_BIT);
  }

  void CALLBACK myReshape(GLsizei w,GLsizei h)
  {
    glViewport(0,0,w,h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if(w<=h)
      glOrtho(-1.5,1.5,-1.5*(GLfloat)h/(GLfloat)w, 1.5*(GLfloat)h/(GLfloat)w,-10.0,10.0);
    else
      glOrtho(-1.5*(GLfloat)h/(GLfloat)w, 1.5*(GLfloat)h/(GLfloat)w,-1.5,1.5,-10.0,10.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
  }

  void CALLBACK display(void)
  {
    glColor3f(1.0,1.0,0.0);
    auxWireSphere(1.0);
    glFlush();
  }

  void main(void)
  {
    auxInitDisplayMode(AUX_SINGLE|AUX_RGBA);
    auxInitPosition(0,0,500,500);
    auxInitWindow("AUX_SAMPLE");
    myinit();
    auxReshapeFunc(myReshape);
    auxMainLoop(display);
  }


圖6-1 網狀球體

  以上程式執行結果是在螢幕視窗內繪製一個黃色的網狀球體,這個程式充分體現了輔助庫的基本應用方法。
  首先,在主函式中用輔助庫函式定義一個視窗auxInitWindow(),然後初始化顏色myinit(),這些在第一章中已說明。接下來是兩個十分重要的函式 auxReshapeFunc()和auxMainLoop(),引數都是一個函式指標,指向的都是回撥函式(回撥函式定義用CALLBACK說明)。
  前者是視窗形狀重定函式,引數指標指向函式myReshape(),它的兩個引數就是視窗的新寬度和新高度。然後用glViewport(0, 0, w, h)重定視口,並且在新視口內重新定義投影矩陣,

glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  if(w<=h)
    glOrtho(-1.5,1.5,-1.5*(GLfloat)h/(GLfloat)w, 1.5*(GLfloat)h/(GLfloat)w,-10.0,10.0);
  else
    glOrtho(-1.5*(GLfloat)h/(GLfloat)w, 1.5*(GLfloat)h/(GLfloat)w,-1.5,1.5,-10.0,10.0);


  即先用glMatrixMode()說明當前矩陣操作與投影有關GL_PROJECTION,再用glLoadIdentity()將矩陣清為單位矩陣,避免受其它矩陣操作的干擾;然後呼叫glOrtho()對物體進行正射投影,並且用判斷語句給出了兩種情況,使投影后影象的比例與視點匹配,避免比例失調。
  再下來呼叫glMatrixMode()將矩陣操作改為對觀察物體有關的方式GL_MODELVIEW,同樣用 glLoadIdentity()清矩陣。後者是主函式迴圈函式,引數指標指向函式display(),即繪製物體。當視窗需要更新或物體發生改變時,程式便呼叫它重新繪製。以上例子是輔助庫的最基本應用,複雜的應用將在後續的章節中詳細介紹。 



七、OpenGL建模

  OpenGL基本庫提供了大量繪製各種型別圖元的方法,輔助庫也提供了不少描述複雜三維圖形的函式。這一章主要介紹基本圖元,如點、線、多邊形,有了這些圖元,就可以建立比較複雜的模型了。

相關推薦

OpenGL基礎圖形程式設計(一)OpenGL與3D圖形世界

一、OpenGL與3D圖形世界1.1、OpenGL使人們進入三維圖形世界  我們生活在一個充滿三維物體的三維世界中,為了使計算機能精確地再現這些物體,我們必須能在三維空間描繪這些物體。我們又生活在一個充滿資訊的世界中,能否儘快地理解並運用這些資訊將直接影響事業的成敗,所以我

OpenGL基礎圖形程式設計--紋理對映

12.1 基本步驟     計算機三維圖形通過給面貼紋理來表現表面細節。OpenGL預設設定是關閉貼紋理的,所以必須先用命令開啟紋理計算。OpenGL體系內有一塊紋理記憶體,在有硬體加速的情況下,可能是位於顯示卡的VRAM裡,否則會是OpenGL庫管理的一塊記憶

OpenGL基礎圖形程式設計(九)OpenGL顏色

九、OpenGL顏色   幾乎所有OpenGL應用目的都是在螢幕視窗內繪製彩色圖形,所以顏色在OpenGL程式設計中佔有很重要的地位。這裡的顏色與繪畫中的顏色概念不一樣,它屬於RGB顏色空間,只在監視器螢幕上顯示。另外,螢幕視窗座標是以象素為單位,因此組成圖形的每個象素都有

OpenGL基礎圖形程式設計

一、OpenGL與3D圖形世界 1.1、OpenGL使人們進入三維圖形世界   我們生活在一個充滿三維物體的三維世界中,為了使計算機能精確地再現這些物體,我們必須能在三維空間描繪這些物體。我們又生活在一個充滿資訊的世界中,能否儘快地理解並運用這些資訊將直接影響

【一篇文章帶你讀完《C++遊戲與圖形程式設計基礎 第2版》】

《C++遊戲與圖形程式設計基礎 第2版》 下載地址:https://download.csdn.net/download/qq_23996157/10745496 AGK(App Game Kit)下載地址:https://download.csdn.net/download/qq_2

3D 圖形程式設計的數學基礎 1 向量及其運算

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

3D 圖形程式設計的數學基礎 3 矩陣基本變換

                     這裡開始,是真正的與3D圖形程式設計相關的知識了,前兩節只能算是純數學。    平移矩陣  要想將向量(x, y, z, 1)沿x軸平移個單位,沿y軸平移,沿z軸平移個單位,我們只需要將該向量與如下矩陣相乘。  N(p) =   從中可以看出4*4矩陣N中的N41,N

3D 圖形程式設計的數學基礎(3) 矩陣基本變換

這裡開始,是真正的與3D圖形程式設計相關的知識了,前兩節只能算是純數學。 平移矩陣 要想將向量(x, y, z, 1)沿x軸平移個單位,沿y軸平移,沿z軸平移個單位,我們只需要將該向量與如下矩陣相乘。 N(p) = 從中可以看出4*4矩陣N中的N41,

高階圖形程式設計(基於opengl)——開譯說明

        TOM McREYNOLDS 和DAVID BLYTHE 寫的這本書,讀好感覺特別好,對圖形程式設計進階有很好的幫助,今天決定開始翻譯一下這本書,也是學習英語的目的吧 概述 計算機圖形學從早期的線框圖和游標距離現在已經很久了。今天任何人都可以有一臺可以

Qt OpenGL:學習現代3D圖形程式設計之二,玩轉色彩

        除了給三角形賦予單一的顏色,我們還有兩種方法來改變三角形表面的顏色,一種是利用片段的位置來計算顏色,另一種是利用每個頂點的資料來計算顏色。 一、利用片段位置計算顏色         片

GDI+ 繪圖基礎-圖形設備&創建Graphics對象

event .net window end object 系統 rgs tar 向量 @1.圖形設備接口 GDI+(Graphcis Device Interface Plus,圖形設備接口)是Microsoft.Net中實現圖形、圖像及文字處理的W32API。所有的GDI

java基礎----網路程式設計 tcp

package cn.itcast.tcp; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.n

Java基礎---網路程式設計 ip udp

package cn.itcast.ip; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; /*  網路程式設計

Python圖形程式設計探索系列-06-按鈕批量生產函式

設計任務 初步設計一個批量生產按鈕的函式,根據需要的按鈕數量,自動生成多少按鈕。 函式設計 import tkinter as tk # 匯入tkinter庫 root = tk.Tk() # 建立程式主視窗 root.title("Button按鈕的自動生成函式") # 設定主視窗的標題 def

對零基礎學習程式設計路線建議

小碼哥教育的初衷是讓大家瞭解程式設計學習,少走一些彎路,少踩一些坑。首先,你們要了解科班出身的學生和零基礎非科班出身的學生區別在哪兒?科班出身的學生,主要是基礎更為了解,但兩者最大的區別還是,科班的學生知道去自學,大學的程式設計課並不一定就講了很多知識,但一定講了程式設計思維。那作為一個零基礎的程式設計初

Python圖形程式設計探索系列-05-用控制變數構建對話程式

跳轉到自己的部落格 控制變數 變數 符號 意義 預設值 1 var = tk.BooleanVar() 布林型 0 2 var = tk.StringVar()

3D數學基礎:圖形與遊戲開發_讀書筆記04

第六章3D介面類 這本書的第六章主要寫了一個工具類,用作之前所描述的概念中向量的計算還有一些運算子的過載,是用C++寫的。 因經驗等原因.我對程式碼設計方面還不是很瞭解,也沒有系統學習過C++,,總之先貼出本書章節中的C++程式碼。 #include<math.h>

3D數學基礎:圖形與遊戲開發_讀書筆記02

第四章概念(這一章也仍然是概念居多,應該要下一章才開始是計算的玩意) 標量 標量是數字的技術稱謂,使用這個詞是想突出數值 向量 向量(或稱向量)是明確帶有大小和方向的數學物件,在程式裡通常表現為陣列。 水平書寫的被稱為行向量,垂直書寫的被稱為列向量 行向量 [1,2,3] 列

3D數學基礎:圖形與遊戲開發_讀書筆記01

前三章內容摘要 通常技術書籍第一章都是為了介紹技術背景,數學書為了循序漸進也是很基礎的東西。就把重要的知識點抓出來 1)研究自然數和整數的領域稱作離散數學,研究實數領域叫做連續數學。 2)3D座標是由2D笛卡爾座標系衍生出來的,xz表示地面,y表示高度,而且上存在著3D兩種座標系(圖

python matplotlib基礎圖形

安裝:pip install matplotlib 匯入模組: # 匯入模組 import matplotlib.pyplot as plt # 處理中文正常顯示 plt.rcParams['font.sans-serif'] = ['SimHei'] # 處理 負號 的正常顯示 plt