這個渲染程序是研一下學期的計算機圖形學課程大作業,花了兩三周學習使用了下 openGL 3.3+ 庫,整合出了這個渲染程序,完成於 2013/07/05。
相對於老版本的庫,新版本更開放,給了程序員更多的控制自由度,程序員可以利用自己掌握的圖形學知識,渲染出更炫更高效的場景,但是使用起來更難了。
新版本有一個很重要的新特性 —— 着色語言(Shading Language),着色語言由顯卡執行,功能更強大,效率更高。
新版本的庫不再提供 glu、glut、glaux 等輔助庫,不過有豐富的開源庫可供選擇(參考),本程序選擇如下:
Glfw——窗口、鼠標、按鍵等交互管理庫,類似於freeGLUT(GLUT早已停止更新),如果使用 GLFW3,需要注意其相對於 GLFW2 接口變了很多,參考:Moving from GLFW 2 to 3;
Glew——openGL擴展(OpenGL Extensions)處理庫,方便我們調用擴展(注意,此庫要調用顯卡 openGL 庫,切記要包含 opengl32.lib);
Glm——數學庫,用於矩陣處理,如各種變換(新版openGL將矩陣處理函數移出核心);
FreeImage——圖片處理庫,用於讀取圖片,提取紋理;
源碼托管在 Github 上:點擊進入鏈接,已包含所有外部庫,有比較詳細的注釋。
編譯前請更新顯卡驅動到最新版,這次在 Win8.1x86+VS2010+AMD Radeon HD 7450 上測試 OK,詳情見下面的報告。
編譯后的可執行程序:點擊進入鏈接,包含附件動態鏈接庫和運行說明,ps:從 cmd 運行可看到一些 printf 出來的運行狀態。
一、相關概念介紹
1、openGL簡介
OpenGL是個專業的3D程序接口,是一個功能強大,調用方便的底層3D圖形庫。OpenGL的前身是SGI公司為其圖形工作站開發的IRIS GL。IRIS GL是一個工業標准的3D圖形軟件接口,功能雖然強大但是移植性不好,於是SGI公司便在IRIS GL的基礎上開發了OpenGL。OpenGL的英文全稱是“Open Graphics Library”,顧名思義,OpenGL便是“開放的圖形程序接口”。雖然DirectX在家用市場全面領先,但在專業高端繪圖領域,OpenGL是不能被取代的主角。
2、OpenGL擴展(OpenGL Extensions)
OpenGL和Direct3D比較起來,最大的一個長處就是其擴展機制。硬件廠商開發出一個新功能,可以針對新功能開發OpenGL擴展,軟件開發人員 通過這個擴展就可以使用新的硬件功能。所以雖然顯卡的發展速度比OpenGL版本更新速度快得多,但程序員仍然可以通過OpenGL使用最新的硬件功能。 而Direct3D則沒有擴展機制,硬件的新功能要等到微軟發布新版DirectX后才可能支持。
每個擴展都有一個擴展名,擴展名類似形式:GL_ARB_multitexture
第一段GL,用來表示針對OpenGL哪部分開發的擴展,有以下幾個值:
GL – 針對OpenGL核心的擴展
WGL – 針對Windows平台的擴展
GLX – 針對Unix / Linux平台的擴展
GLU – 針對OpenGL Utility Library的擴展
第二段ARB,用來表示是誰開發的這個擴展,ARB是經OpenGL Architecture Review Board(OpenGL管理機構)正式核准的擴展,往往由廠商開發的擴展發展而來,如果同時存在廠商開發的擴展和ARB擴展,應該優先使用ARB擴展,常見的還有以下幾個值:
EXT – 被多個硬件廠商支持的擴展
NV – NVIDIA 公司開發的擴展
ATI – ATI公司開發的擴展
ATIX– ATI公司開發的實驗性擴展
SGI – Silicon Graphics(SGI)公司開發的擴展
SGIX– Silicon Graphics(SGI)公司開發的實驗性擴展
第三段multitexture就是真正的擴展名了,如multitexture就是多重紋理擴展。
3、緩沖器對象(buffer object)
在許多OpenGL操作中,我們都向OpenGL發送一大塊數據,例如向它傳遞需要處理的頂點數組數據。傳輸這種數據可能非常簡單,例如把數據從系統的內存中復制到圖形卡。但是,由於OpenGL是按照客戶機-服務器模式設計的,在OpenGL需要數據的任何時候,都必須把數據從客戶機內存傳輸到服務器。如果數據並沒有修改,或者客戶機和服務器位於不同的計算機(分布式渲染),數據的傳輸可能會比較緩慢,或者是冗余的。
OpenGL 1.5版本增加了緩沖區對象(buffer object),允許應用程序顯式地指定把哪些數據存儲在圖形服務器中。
當前版本的OpenGL中使用了很多不同類型的緩沖區對象:
從OpenGL 1.5開始,數組中的頂點數據可以存儲在服務器端緩沖區對象中。
在OpenGL 2.1中,加入了在緩沖區對象中存儲像素數據(例如,紋理貼圖或像素塊)的支持。
OpenGL 3.1增加了統一緩沖對象(uniform buffer object)以存儲成塊的、用於着色器的統一變量數據。
OpenGL中有很多其他的功能用到了術語“對象”,但是這些功能並不都適用於存儲塊數據。例如,(OpenGL 1.1引入的)紋理對象只是封裝了和紋理貼圖相關聯的各種狀態設置。同樣,OpenGL 3.0中增加的頂點數組對象,封裝了和使用頂點數組相關的狀態參數。這些類型的對象允許我們使用較少的函數調用就能夠修改大量的狀態設置。為了使性能最大化,只要習慣它們的操作,就應該盡可能地嘗試使用它們。
注意:通過對象的名字來引用它,其名字是一個無符號的整型標識符。從OpenGL 3.1開始,所有的名字必須由OpenGL使用glGen*()函數之一來生成,不再接受用戶定義的名字。
4、着色語言(Shading Language)
OpenGL 1.5還新增了“OpenGL Shading Language”,該語言是“OpenGL 2.0”的底核,用於着色對象、頂點着色以及片斷着色技術的擴展功能。
使用Shading Language編寫的程序稱之為Shading Program(着色程序)。着色程序分為兩類:Vertex Shading program(頂點着色程序)和Fragment Shading Program(片斷着色程序),它們分別被Programmable Vertex Processor(可編程頂點處理器)和 Programmable Fragment Processor(可編程片斷處理器)所執行。
頂點着色程序從GPU前端模塊(寄存器)中提取圖元信息(頂點位置、法向量、紋理坐標等),並完成頂點坐標空間轉換、法向量空間轉換、光照計算等操作,最后將計算好的數據傳送到指定寄存器中;然后片斷着色程序從中獲取需要的數據,通常為“紋理坐標、光照信息等”,並根據這些信息以及從應用程序傳遞的紋理信息(如果有的話)進行每個片斷的顏色計算,最后將處理后的數據送光柵操作模塊。
二、實驗介紹
1、實驗目的:
用openGL渲染一個場景:
多個物體,不同組織方式;
物體有的靜止,有的旋轉;
物體有不同紋理;
物體有彩色透明的,可透視其他物體;
平行光照模型,含有環境光和漫反射光;
有一個虛擬太陽,可調整平行光的方向;
天空盒,美化單調的背景。
2、實驗環境:openGL 3.3、VS2010、XP SP3、ATI Mobility Radeon HD 5145
3、相關庫文件
Glfw——窗口、鼠標、按鍵等交互管理庫,類似於freeGLUT(GLUT早已停止更新);
Glew——openGL擴展(OpenGL Extensions)處理庫,方便我們調用擴展;
Glm——數學庫,用於矩陣處理,如各種變換(新版openGL將矩陣處理函數移出核心);
FreeImage——圖片處理庫,用於讀取圖片,提取紋理;
4、源文件結構
common_header.h——通用頭文件;
shader.h、shader.cpp——着色器程序類,創建、載入、編譯着色器源碼,創建、鏈接、運行着色器程序;
glCamara.h、glCamara.cpp——照相機類,處理前后左右移動和鼠標的旋轉;
skybox.h、skybox.cpp——天空盒類,載入天空紋理,渲染天空盒;
static_geometry.h、static_geometry.cpp——幾個物體的位置、紋理坐標、法向量;
vertexBufferObject.h、vertexBufferObject.cpp——VBO,頂點緩沖區對象,組織上述各種坐標信息並載入顯存;
renderScene.h、renderScene.cpp——主場景渲染程序,初始化各種場景參數,場景渲染代碼;
glmain.cpp——main文件,窗口參數設置及創建,調用上述場景渲染函數生成渲染主循環;
4.1着色器文件:
shaderSky.vert——天空盒頂點着色器源碼
shaderSky.frag——天空盒片段着色器源碼
shaderTex.vert——紋理物體頂點着色器源碼
shaderTex.frag——紋理物體片段着色器源碼
shaderCol.vert——透明箱子頂點着色器源碼
shaderCol.frag——透明箱子片段着色器源碼
5、可執行程序使用說明
(1)運行條件:openGL 3.3或更高,如果版本低,請先更新顯卡驅動
(2)注意事項:
如果從CMD運行,可以看到運行記錄;這樣,如果異常退出,可以看到錯誤提示;
運行時請勿按Win鍵,以防假死;
(3)控制說明:
esc鍵退出;
w、s、a、d 鍵控制前后左右移動,鼠標控制視角;
左右方向鍵控制太陽(平行光)位置;
6、運行截圖(太陽分別從右上、左上、下照耀)