OpenGL 基礎入門

OpenGL 需要用到的數學知識:


空間解析幾何,矢量代數。


世界座標系: 有三維 x,y,z 軸,是 右手座標系。


向量:在一個座標系中,兩個點位置之間的差,可認爲是一個有向線段。


矩陣: 由mxn個數排成的m行n列的數表。


對於OpenGL剛入門的朋友,推薦大家看一下以下這些知識:Programming Guide (紅寶書). PDF and HTML, 橙寶書 ("OpenGL Shading Language"), 以及 NeHe's OpenGL教程。


OpenGL windows 環境搭載:

在windows開發openGL可以使用vc,也可以用devc++,後者是免費軟件。

我們講一下如何使用devc++。


安裝成功以後,創建一個新工程,工程裏面就有一個openGL工程,創建好openGL工程以後,自帶了一個openGL的例子。


接下來我們想把《紅寶書》的例子放到這個IDE中去編譯運行,首先我們去下載源代碼,下載地址是: http://www.opengl.org/resources/code/samples/redbook.zip


打開壓縮包,看到的是一組exe可執行文件和它們的c源文件,雙擊exe文件發現並不能正常運行,報告缺少某些dll文件,我們需要 通過源文件來重新編譯exe文件。


打開一個源文件,把內容copy到我們工程裏面的main.cpp裏面,然後編譯運行,IDE報link錯誤,難點在這裏了。


工具-->檢查更新-->select dev pack server,選擇devpaks.org Community Devpaks

點擊最下方的Check for updates 按鈕,等待加載完成後在groups裏面選擇openGL,會出現多個插件供你選擇安裝,因爲我們的源代碼裏面用到了glut,所以我們需要安裝這個pakage,我們需要選擇openglut就行安裝,而不是選擇glut,這個依然會在link的時候報錯。


安裝完成後,工程--》工程屬性--》參數,加入庫或者對象,選擇以後庫文件:

Lib/libopengl32.a

Lib/libopenglut.a
Lib/libglu32.a

ok,現在你可以編譯和運行openGL例子了!


ps: 如果使用了aux library,一定要把Lib/libaux.a 放在Lib/libopengl32.a 之前。


----OpenGL 紅寶書----


----chapter 1 開始-----


1. openGL 是對圖形硬件的一組接口,這些接口包含了120個命令。


2. openGL 有客戶端和服務端的概念,openGL可以工作在網絡環境中,運行程序和發射openGL命令的計算機稱作客戶端,接受命令並顯示圖形的計算機稱爲服務器端,如果只有一臺機器,則這臺機器既是客戶端又是服務器端。


3.openGL被設計爲硬件無關,所以它並沒有提供跟窗口和用戶輸入相關的接口。


4. 把圖形對象的數學描述和顏色信息轉化成屏幕上的像素的過程,稱爲光柵化。


5. 兩個圖形有遮擋的情況下,爲了提高性能,被遮擋的部分不被畫出來。


6. bitplane存儲了屏幕像素的顏色信息,或者說某個像素到底有多紅。


7. openGL命令習慣於使用後綴表示參數的數量和類型,比如: glColor3f()   表示這個方法有三個參數,而且類型是單精度浮點型;幾乎每個命令都有vector版本,即參數是一個vector(數組,序列)。


8. openGL 是個狀態機,你對openGL的一次配置都會影響到接下來的繪圖工作,比如你設置了顏色,如果在接下來 不顯示改變繪圖顏色,那麼所有圖形將使用你之前設置的顏色進行繪圖。


9. 有一些庫封裝了openGL的基本函數,使openGL的使用更方便,如GLU,這個庫是跟openGL的實現一起發行的; GLX,這個庫是專門用於x windows 系統的;Open Inventor 是一個openGL的面向對象工具箱。

10. 圖形編程中,雙緩衝技術是常用的一種圖形繪圖技術,先將圖形繪製在內存中,完成以後再投影在到屏幕上,這樣不會 因爲頻繁的屏幕刷新操作引起屏幕閃爍。


11. 要做到動畫的產生,需要至少每秒鐘在屏幕上順序顯示24幀的圖片,在呈現每一張的圖片的過程中,我們不要把畫的過程呈獻給用戶,當圖片畫好以後再投影到屏幕上,而第一張再投影的時候,後臺應該在繪製第二張需要投影的圖片,這就是雙緩衝技術的一個使用。


動畫製作過程中遇到的問題:

12. 假如一個機器支持的最高刷新率是60幀每秒,如果你可以在1/60之內把圖片繪製完成,那麼我們就可以得到最高的刷新率,即每秒60幀,這樣的圖像看起來也是最流暢的;但是如果我們的圖片非常複雜,繪製一張圖片需要1/45秒,而且在繪製完成之前是不能投影到屏幕上的,防止用戶看到不完整的圖片,那我們在只能在兩個1/60內顯示同一張圖片,屏幕的實際幀數就降到了每秒30幀,假如隨着程序的執行過程中我們需要繪製越來越複雜的圖片,那麼每秒顯示的幀數可能繼續降低,越來越不流暢,甚至畫面卡住。


13. 因爲畫每一張圖片的時間是隨機的,有可能低於一次刷新也有可能高於一次刷新,所以動畫看起來就可能時快時慢,這種情況下最好設置一個更長的刷新週期,讓動畫播放的慢點。


----chapter 1 結束-----


----chapter 2 開始-----

1. 不管多麼複雜的圖片都是由最基本的圖形組成的,這些基本圖形有點、線、二維多邊形等。


2. openGL畫圖過程:清空屏幕、繪製基本幾何圖形、繪製光柵對象。


3. openGL 默認的是即畫即顯得模式,當你向發出一個openGL命令時,顯示會更新,作爲增強,可以維護一個openGL的命令隊列。


4. 畫圖之前一般要先清空屏幕到指定的背景,比如要畫word文件清空到白色,要繪製星空的清空到黑色,但是有時候也不需要清空,比如換了一個場景,從室外轉到了室內。


5. 很多系統都有很多緩衝作爲顏色緩存,這些緩存都需要被實時的更新,最好有一個這樣的例程做這些工作。


6.  RGBA 顏色: RED , GREEN, BLUE, ALPHA. 範圍都是【0,1】閉區間,alpha = 0 完全透明, alpha = 1 完全不透明。


7.  完全的紅,綠,藍混合成白色,一點都沒有的混合成黑色,紅和綠混合成黃色,紅和藍混合成品紅,綠和藍混合成藍綠。三個各一半是灰色(介於黑色和白色之間)。


8. 一般情況下,client端會把openGL命令裝進一個network package,等這個package滿了以後,就可以把它發給server端,然而如果package一直不滿,就有可能一直等待下去。這時我們可以使用glFlush(),它命令將不滿的package發送出去。

還有一個函數glFinish()執行和glFlush()一樣的事情以後,等待server端將圖形繪製完畢的消息,這個方法可以用在需要繪製有先後順序,或者事件需要同步的場合。


9.  如何處理圖形建的遮擋,爲每個像素設置深度信息,這裏使用一個深度緩衝表,當新圖形的深度比舊圖形的深度淺時,就把那個像素設置成新的,反之拋棄,由於像素被拋棄而不是用來 繪製,可以提高性能。


10. openGL 中的點、線、多邊形 和數學中的概念有點不一樣,而且知道它們的區別很重要,openGL中的點是有三維的,不過z軸通常被置爲0,數學中的點是無窮的小的,在openGL中明顯不是,他起碼佔一個像素,還有可能佔更多;數學中的線是無窮細而且在兩端無窮眼神的,openGL中指的是有寬度的線段;openGL中的多邊形是凸多邊形,而且不能有洞,凹多邊形可以由凸多邊形構成。


11. OpenGL中所有的幾何圖形都是由頂點組成的。可以使用glVertex*()來指定一個頂點。這個方法的調用應該在glBegin()和glEnd()之間。


12. 在繪製幾何圖形的時候,告訴openGL你要畫什麼,然後指定幾個頂點, 繪製語句是要區分順序的,順序變了,畫出的圖形可能也就不一樣了。


例:繪製圓圈:

#define PI 3.1415926535897;

GLint circle_points = 100;

glBegin(GL_LINE_LOOP);

for (i = 0; i < circle_points; i++) {

angle = 2*PI*i/circle_points;

glVertex2f(cos(angle), sin(angle));

} glEnd();

13. 默認的情況下,點佔一個像素,線有一個像素寬,多邊形是被填充的。但opengGL提供了定製接口 。

Point Details

你可以使用glPointSize(size)用像素數來指定點的寬度,這裏有一個抗鋸齒的概念:

如果抗鋸齒功能沒有開,啓, 當一個點的像素數量不是一個整數的時候,系統會自動把這個數量約等於爲整數,然後畫出一個正方形區域,

這樣我們看起來的圖像是不平滑的;

如果開啓了抗鋸齒的功能, 會畫出一個圓形的區域,而且這個區域的邊緣像素的亮度不是滿的,這樣可以讓圖像看起來更平滑,

在這個模式下,非整數寬度是不會被截取爲整數的。

不抗鋸齒的點的寬度的上限是抗鋸齒寬度上限約爲整數的值,可以用glGetFloatv(GL_LINE_WIDTH_RANGE)得到抗鋸齒點的寬度的上限。

Line Details

線的寬度和點的寬度的概念是相同的,同樣要區分抗不抗鋸齒,這裏需要注意的是線的寬度默認是1個像素寬,在低分率的屏幕上,線的寬度可能比較明顯,而高分辨率的屏幕上,一個像素的寬度有可能讓你根本看不見那條線,而要實現分辨率無關的線寬,需要把像素的物理寬度計算進來。



待續。。。。。。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章