1. 程式人生 > 其它 >《計算機圖形學程式設計》筆記——第二章

《計算機圖形學程式設計》筆記——第二章

技術標籤:圖形學圖形學opengl

《計算機圖形學程式設計》筆記——第二章

OpenGL影象管線

現代3D圖形學程式設計會使用管線的概念,在管線中,將3D場景轉換為2D圖形的過程被分成多個步驟。實際上,圖形學做的事情,筆者是這樣理解的:構建三維模型,隨後採用虛擬相機對該模型進行拍攝,最終呈現在使用者眼前。這個過程需要考慮成像原理、成像效果等。

影象管線介紹

採用GLSL進行程式設計,流程可以分為下列幾步:

1. 頂點著色器

圖形學中包含點、線、三角形等圖元,多數3D模型通常都是由許多三角形的圖元構成。圖元由頂點組成,即我們所說的3D點,這些3D點的來源有多種:硬編碼於程式中(即給定陣列)或者從檔案中載入緩衝區等方法。
不論頂點從何處傳入,都會被傳入頂點著色器,被逐一處理。
頂點著色器擁有一次操作一個頂點的能力。

2. 曲面細分著色器

OpenGL有一個可程式設計曲面細分階段,提供一個曲面細分著色器用於生成大量三角形,通常是網格形狀,同時提供各種方式操縱這些三角形的工具。
當在簡單形狀上需要很多頂點時,曲面細分著色器就能發揮作用了。
有時用GPU中的曲面細分著色器在硬體裡生成三角形網格比在C++中生成要高效得多。

3. 幾何著色器

按圖元處理有很多用途,既可以讓圖元變形,比如拉伸或者縮小,還可以刪除一些圖元,從而在渲染的物體上產生“洞”——這是一種將簡單模型轉化為複雜模型的方法。
幾何著色器擁有一次操作一個圖元的能力(按圖元處理)。

4. 光柵化

3D世界中的點、三角形、顏色等全都需要展現在一個2D顯示器上。這個2D螢幕由光柵——矩陣畫素陣列組成。
光柵化過程開始時先對三角形的每對頂點進行插值,比如漸變的顏色,實現真實光照等。

5.片段著色器

片段著色器用於為光柵化的畫素指定顏色。

6. 畫素操作

在繪製場景中的物體時,我們通常希望前面的物體擋住後面的物體。為了實現這個效果,我們需要隱藏面消除。

實現隱藏面消除的方法是使用兩個緩衝區:顏色緩衝區和深度緩衝區實現。

程式碼及結果

這一講中,我們將書中的程式碼進行整理並修改,使其適用於Linux系統。

詳情可以參考程式碼:cg_book_practice/chapter_2/

我們對每一個測試程式碼都輸出了視覺化結果,可以檢視README.md檔案,方便大家理解我們程式碼做的事情。並且程式碼中關鍵的地方,筆者都參考課本以及查閱的資料做了註釋,便於理解。

drawPointtriangleMoving

BUG

這一講中提供了:檢查OpenGL和GLSL錯誤 相關的內容,於是筆者對關鍵的部分進行了Bug檢查。

1. GLEW初始化:glError:2080

值得注意的是,我們發現了一個glError:2080。通過查閱資料發現,這是一個無效列舉導致的錯誤,多次定位以後發現是在初始化GLEW時出現的。而這個問題,筆者查了很久,最後發現是版本的問題,具體的描述可以在官網上查到:OpenGL Loading Library,emmm…純粹來噁心人的。

另外,在Linux下初始化GLEW之前,需要設定 glewExperimental=TRUE,否則程式會直接崩潰,emmm…這也是官網提供的要求,媽蛋困擾了筆者不少時間。

2. 顏色緩衝區重新整理

在實現點的增大和縮小程式中,筆者在display函式中忽略了顏色緩衝區的重新整理,導致點的縮小和變大顯示錯誤,最後發現是因為顏色緩衝區沒重新整理。

首先採用清除顏色緩衝區,隨後採用預設的顏色填充整個緩衝區,可以實現螢幕的重新整理,防止色彩滯留,與下一幀的顏色重疊,導致顯示出錯。

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

引用

[1] OpenGL Loading Library
[2] cg_book_practice/chapter_2/