本書系列html
現代3D圖形編程學習linux
在咱們編寫openGL程序以前,咱們首先須要知道什麼是OpenGL。編程
OpenGL 一般被認爲是應用程序接口(API)。OpenGL API有不一樣編程語言的實現版本。可是,它們最終使用的都是最底層的C語言的接口。windows
在C語言的API中,定義了不少typedefs,#define,以及函數。typedefs用於定義openGL裏面使用到的基本的數據類型,如GLint,GLfloat等。api
複雜的數據結構,如struct,在openGL中沒有直接暴露給用戶,都是隱藏在一系列的API背後。這樣有利於將OpenGL API改寫成非C語言實現的版本。數組
在C++中,若是你想要一個包含整型,浮點型和字符串的類型,你會採起下面的措施實現:數據結構
struct Object { int count; float opacity; char *name; } // Create the storage for the object Object newObject; // Put data into the object newObject.count = 5; newObject.opacity = 0.4f; newObject.name = "Some String";
在opengl中,採用api的方式實現,以下:架構
// Create the storage for the object GLuint objectName; glGenObject(1, &objectName); // Put data in to the object glBindObject(GL_MODIFY, objectName); glObjectParameteri(GL_MODIFY, GL_OBJECT_COUNT, 5); glObjectParameteri(GL_MODIFY, GL_OBJECT_OPACITY, 0.4f); glObjectParameteri(GL_MODIFY, GL_OBJECT_NAME, "Some String");
上述的例子中,並非真實的opengl的命令,僅僅用來講明,在opengl中一個對象是怎麼經過api的方式建立以及賦值的。app
opengl本身擁有存儲全部opengl對象的存儲空間。所以,用戶只可以經過引用的方式來訪問對象。幾乎全部的opengl對象都會被綁定到一個非符號整型(GLuint)。對像會被相似於glGen*的函數建立,星號表示的對象的類型。第一個參數表示有多少個對象要被建立,第二個參數用來接受建立的對象的名字。編程語言
大多數對象首先須要被綁定到上下文,纔可以被更改。不少對象能夠被綁定到上下文的不一樣的位置,這就容許一個對象以不一樣的方式被使用。這些不一樣的位置被稱爲「targets」,全部的對象都擁有一個合法的目標列表,有些對象僅有一個目標。在上面的例子中,GL_MODIFY是objectName
被綁定到的位置。
GL_OBJECT_*
形式命名的枚舉,是這個對象中可以被賦值的屬性。glObjectParameter
這類的函數,做用是將對象中的參數綁定到給定的目標上。因爲opengl的api是c語言版本的,對於不一樣類型入參的函數,必須以不一樣函數名分別開來,如glObjectParameteri
針對整型入參,glObjectParameterf
針對浮點型入參。
須要注意的是,opengl中的對象並非都想示例中這麼簡單,有些改變對想法狀態的函數,也和示例中函數的形式不一樣。那麼,將一個對象綁定到上下文具體是什麼意思呢,在下面會有解答。
opengl的api被定義爲狀態機。幾乎全部的opengl函數都是設置或是獲取相應的狀態。沒有用來改變對象狀態的惟一一類函數是,利用這些設進去的狀態,來觸發渲染的行爲。
你能夠將這個狀態機設想成一個很大的,帶有不少不一樣屬性的數據結構。這樣的數據結構被稱爲「opengl context」,上下文中的每個屬性都包含了一些用於渲染的必要的信息。
opengl中的對象被定義成上下文中的一系列的屬性,而且能夠被保存和恢復。將一個對象綁定到一個目標,就是將對象中的屬性替換掉上下文對應目標上的屬性。所以在綁定以後,後續的函數將會從上下文中調用到剛剛更新了的內容。
對象一般用GLuint表示,這些整數是連接opengl實際對象的句柄。0是一個特殊的數字,與null指針具備相似的含義。將目標綁定到0,意味着對當前綁定的對象解綁。也就是說,對應的上下文中的內容會恢復到初始狀態,恢復到綁定發生以前的狀態。
opengl上下文相似於:
// Opengl Object Example struct Values { int iValue1; int iValue2; }; // Opengl Context Example struct OpenGL_Context { ... Values *pMainValues; Values *pOtherValues; ... }; OpenGL_Context context;
要建立一個Values
對象,你將要調用相似與glGenValues
的函數,而後你要將建立的對象綁定到上下文的目標位置,如GL_MAIN_VALUES
表示指針context.pMainValues
,GL_OTHER_VALUES
表示指針context.pOtherValues
。你將經過glBindValues
分別將對象綁定到對應的目標上。這將會使得上下文中的指針指向你建立的對象。
也有用於設置綁定對象內參數的函數,glValueParam
。它將獲取對象的目標位置,也就是上下文中的那個指針。也會獲取一個枚舉用來表示對象中的哪一個值會被改變。如GL_VALUE_ONE
來表示iValue1
,GL_VALUE_TWO
用來表示iValue2
。
從技術上來講,opengl並非api,而是一個規範。一個文檔。c api僅僅是對這個規範的一種實現。這個規範定義了opengl初始狀態,每個函數對於改變狀態和獲取狀態可以作些什麼,當你調用渲染函數的時候,哪些會發生。
這個規範是OpenGL架構審查委員會書寫的。這個機構的表明有Apple,NVIDIA和AMD等。這個委員會是Khronos Group的一部分。
這個規範是很是複雜的技術文檔。可是,其中的部份內容是很容易理解的。若是你嘗試去讀這個文檔,你會發現這個文檔注重對結果的描述,而不是具體實現。也就是說,若是硬件的一部分以不一樣的實現方式提供了相同的結果,用戶是沒法分別出來的。
opengl的實現 儘管opengl ARB控制了opengl的規範,可是它並無控制代碼自己。opengl並不能經過軟件中心進行下載。它的實現徹底取決於硬件開發商,根據opengl規範,進行實現。
針對不一樣的操做系統,都有不一樣的人員來控制opengl的實現。針對windows操做系統,opengl的實現是受硬件開發商本身控制的。在Mac OSX操做系統,opengl的實現是受apple公司控制的,他們決定提供給用戶opengl的哪一個版本,以及哪些擴展。而,針對linux系統,事情就變得有點複雜了。
簡單的講,若是你寫的程序超出了規範中約定的行爲,這個就是你的opengl實現商的問題了(假設你的代碼中並無bug)。在windows系統,他們的opengl實現是附帶在不一樣的圖形硬件驅動中的。所以,假如遇到了他們實現版本的問題,一般能夠採用升級驅動的方法,也許這個問題已經在最新的驅動中解決了。
opengl版本 目前已經有了不少不一樣版本的opengl規範。opengl的版本並不像大多數一般會改變大多數api的direct3d版本。在一個opengl版本中可以運行的代碼,基本能夠在更新的版本中運行。
惟一須要注意的是,正確處理opengl3.0和以上的版本,和3.0以前的版本之間的關係。在3.0版本的時候,讓不少舊接口過期了。在3.1版本的時候將這些過期的接口中的大部分都刪除了。同時將規範分解成了兩個變種,核心的和兼容的。兼容的部分包含了3.1版本刪除的全部舊的函數,然而在覈心的部分並無這麼作。理論上,opengl規範僅僅須要核心的部分,可是這會讓不少原來以來於老接口函數的功能沒法正常工做。
做爲一個實際問題,這些都不重要。沒有一個opengl驅動開發者會僅僅實現核心的部分。所以,opengl徹底是向下兼容的。
一個由帶順序的其餘數值組成的值。向量中存儲的數字的個數稱爲維度。向量擁有屬於本身的數學操做。
單個,非向量數值,也能夠考慮成是一個維度的向量。
表示一個位置的向量
表示一個方向的向量
向量中的每個值
一個操做的效果是分別對向量各個成分進行操做的效果相同,輸出結果的向量的維度和輸入向量的維度相同。
向量長度爲1的向量是單位向量,是純粹的方向向量
將一個向量變成同向的單位向量的過程
數字圖像的最小成分。一個像素擁有顏色空間中的特定顏色
二維的像素數組
將一個3d的世界,從一個特殊的視角轉變成2d圖像的過程
一個特殊的渲染方法,用於將一系列的3d的三角形轉變成2d的圖
由三角形組成的,3d空間中的單個物體
組成三角形的三個元素之一。頂點能夠是任意的數字,用來表示一個點在3d空間中的位置。
由三維空間中的點轉換而來,這個空間中點的位置是4個維度的。第四個維度w表示了裁剪空間的可見區域。所以裁剪座標系中點的xyz成分必須在[-w,w]之間纔是可見的。在裁剪座標系中x的正方向是右,y的正方向是上,z的正方向是遠離觀察者的方向。裁剪座標系中的點是渲染管線中的頂點處理階段的輸出結果。
這個過程是將裁剪座標系中若是有頂點在裁剪空間外面,就發生分割行爲
這個是將裁剪座標系中的點除以w以後的點。這樣,全部的點的成分在[-1,1]範圍內就是可見的。
由標準化設備座標系映射過去的三維空間。這些點的xy的位置和最終圖像的位置是一一對應的。原點在左下方,x正方向爲右,y正方向是上。z值在[0,1]的範圍,0表示最近,1表示最遠。在這個範圍外的點是不可見的。
這個過程是將窗口座標系中的三角形,打成一個個片斷,而後投射到對應的圖像的像素中。
在掃描轉換過程那個中對於三角形像素邊界非連續的位置判斷是否產生片斷的過程。單個像素的區域能夠進行屢次採樣,從而能夠產生過的片斷
掃描轉換後的三角形的單個元素。一個片斷能夠包含任何的數值,可是這個數值要是三維的,用來表示窗口座標系中在三角形中的位置。
opengl提供的一個保證,在頂點處理過程當中相同的輸入擁有相同的輸出。
在計算機圖形學中,用來表示顏色的一個集合。全部的顏色都是在特定的顏色空間的基礎上定義的。
渲染器來執行的程序,用來執行用戶定義的一些行爲
渲染管線中的一個特殊位置,着色程序用來執行的地方。這個階段的執行結果將會做爲下一個階段的輸入。
用來規定渲染系統的規範
會用於渲染的參數的特殊集合。相似於一個很大的c語言中的struct,其中包含了不少不一樣的能夠被訪問的屬性。若是你須要建立多個窗口來處理渲染任務,那麼沒一個窗口都會有本身獨立的opengl上下文
對象能夠綁定到opengl上下文的特定位置上。此時,上下文特定位置的參數指向的內容就是被綁定的對象中設定的內容。同時一個對象能夠被綁定到不一樣的位置,特定類型的對象能夠綁定到不一樣的位點。
針對特殊的系統,對opengl規範實現的軟件