以前學習管線的時候,咱們知道OpenGL的渲染流程是有固定次序的。那麼先了解下渲染框架:前端
這裏的客戶端和服務端都是對OpenGL而言。客戶端將數據和渲染指令發送給服務端。c++
頂點着色器(Vertex Shader)
->圖元裝配(Primitive Assembly)
->片元着色器(Fragment Shader)
->渲染(Render)
。着色器是使用GLSL編寫的程序。GLSL看起來與C語言很是相似,實際上GLSL語言的程序甚至是以咱們熟悉的main函數開始的。這些着色器必須從源代碼中編譯和連接到-起(這一點仍然和C、C++程序很是相似)才能使用。最終準備就緒的着色器程序隨後在第一階段構成頂點着色器,在第二階段構成片斷着色器。請注意,咱們目前討論的是簡化的方式。實際上還有一種幾何着色器能夠(選擇性地)安排在二者之間,就像用來將數據來回傳遞的全部類型的反饋機制同樣。還有一些傳遞片斷的處理特性,諸如混合、模板和深度測試。程序員
頂點着色器處理從客戶機輸入的數據,應用變換,或者進行其餘類型的數學運算來計算光照效果、位移、顏色值,等等。爲了渲染一個共有3個頂點的三角形,頂點着色器將執行3次,也就是爲每一個頂點執行一次。在目前的硬件上有多個執行單元同時運行,這就意味着全部這3個頂點均可以同時進行處理。今天的圖形處理器屬於大規模並行計算機。不要將它們和CPU相比而被時鐘速度矇蔽,它們比圖形操做要快上幾個數量級。編程
如今,3個頂點都作好了光柵化的準備。圖元組合( Primitive Assembly )框圖意在說明3個頂點已經組合在一塊兒,而三角形已經逐個片斷地進行了光柵化。每一個片斷都經過執行片斷着色器而進行了填充,片斷着色器會輸出咱們將在屏幕上看到的最終顏色值。再強調一次,今天的硬件是大規模並行運算的,同時執行上百個甚至更多的這種片斷程序並不困難。後端
在OpenGL核心框架中,並無提供任何內建渲染管線,在提交一個幾何圖形進行渲染以前, 必須制定一個着色器。咱們可使用的存儲着色器。這些存儲着色器由GLTools 的C++類GLShaderManager進行管理,它們可以知足進行一般渲染的基本要求。bash
單位( ldentity )着色器
只是簡單地使用默認的笛卡爾座標系(在全部座標軸上的座標範圍都是1.0~1.0)。全部片斷都應用同一種顏色,幾何圖形爲實心和未渲染的。這種着色器只使用一個屬性GLT_ATTRIBUTE_VERTEX
。vColor參數包含了要求的顏色。框架
GLShaderManager::UseStockShader (GLT_SHADER_IDENTITY, GLfloat vColor[4]);
複製代碼
平面( Flat)着色器
將統一着色器進行了擴展,容許爲幾何圖形變換指定一個4x4變換矩陣。典型狀況下這是一種左乘模型視圖矩陣和投影矩陣,常常被稱做「模型視圖投影矩陣」。這種着色器只使用一個屬性GLT_ATTRIBUTE__VERTEX
。函數
GLShaderManager::UseStockShader(GLT_SHADER_FLAT, GLfloat mvp[16],GLfloat
vCo1or[4]) ;
複製代碼
這種着色器惟一的Uniform 值就是在幾何圖形中應用的變換矩陣。GLT_ATTRIBUTE_VERTEX
和 GLT_ATTRIBUTE_COLOR
在這種着色器中都會使用。顏色值將被平滑地插入頂點之間(稱爲平滑着色)。學習
GLShaderManager::UseStockShader(GLT_SHADER_SHADED, GLfloat mvp[16]);
複製代碼
這種着色器創造出一種錯覺,相似於由位於觀察者位置的單漫射光所產生的效果。從本質上講,這種着色器使對象產生陰影和光照的效果。這裏須要模型視圖矩陣、投影矩陣和做爲基本色的顏色值等Uniform值。所需的屬性有GLT_ATTRIBUTE_VERTEX
和GLT_ATTRIBUTE_NORMAL
。大多數光照着色器都須要正規矩陣( normal matrix )做爲Uniform值。測試
GLShaderManager::UseStockShader(GLT_SHADER_DEFAULT_LIGHT, GLfloat mvMatrix[16], GLfloat pMatrix[16], GLfloat vColor[4]);
複製代碼
點光源着色器和默認光源着色器很類似,可是光源位置多是特定的。這種着色器接受4個Uniform值,即模型視圖矩陣、投影矩陣、視點座標系中的光源位置和對象的基本漫反射顏色。所需的屬性有GLT_ATTRIBUTE_VERTEX
和GLT_ATTRIBUTE_NORMAL
。
GLShaderManager::UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF, GLfloat mvMatrix[16], GLfloat pMatrix[16], GLfloat vLightPos[3], GLfloat vColor[4]);
複製代碼
着色器經過給定的模型視圖投影矩陣,使用綁定到nTextureUnit
指定的紋理單元的紋理對幾何圖形進行變換。片斷顏色是直接從紋理樣本中直接獲取的。所需的屬性有GLT_ATTRIBUTE_VERTEX
和GLT_ATTRIBUTE_NORMAL
。
GLShaderManager::UseStockShader(GLT_SHADER_TEXTURE_REPLACE, GLfloat mvpMatrix[16], GLint nTextureUnit);
複製代碼
這種着色器將一個基本色乘以一個取自紋理單元nTextureUnit 的紋理。所需的屬性有 GLT_ATTRIBUTE_VERTEX
和GLT_AT TRIBUTE_TEXTUREO
。
GLShaderManager::UseStockShader(GLT_SHADER_TEXTURE_MODULATE, GLfloat mvpMatrix[16], GLfloat vColor, GLint nTextureUnit);
複製代碼
這種着色器將一個紋理經過漫反射照明計算進行調整(相乘),光線在視覺空間中的位置是給定的。這種着色器接受5個Uniform值,即模型視圖矩陣、投影矩陣、視覺空間中的光源位置、幾何圖形的基本色和將要使用的紋理單元。所需的屬性有GLT_ATTRIBUTE_VERTEX
、GLT_ATTRIBUTE_NORMAL
和GLT_ATTRIBUTE_TEXTUREO
。
GLShaderManager::UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF, GLfloat mvMatrix, GLfloat pMatrix[16], GLfloat vLightPos[3],
GLfloat vBaseColor[4],GLint nTextureUnit);
複製代碼
固然咱們必須首先爲這些着色器提供數據,不然什麼也作不成。有3種向OpenGL着色器傳遞渲染數據方法可供程序員選擇,即屬性、uniform值和紋理。