1. 固定著色器
1.1 固定存儲著色器的初始化
//定義一個,著色管理器
GLShaderManager shaderManager;
//固定著色器的初始化
shaderManager.InitializeStockShaders();
1.2 固定存儲著色器的類型
1.2.1 單元著色器
- 代碼編寫
//顏色設(shè)置四個參數(shù)分別表示RGBA
GLfloat vColor[] = { 0.3f, 0.6f, 0.1f, 1.0f };
//使用單元著色器繪制圖形
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vColor);
- 使用場景:繪制默認(rèn)OpenGL坐標(biāo)系(-1, 1)下的圖形,圖形所有片段都會以一種顏色填充。
1.2.2 平面著色器
- 代碼片段
//模型投影矩陣
GLfloat mvpMatrix[16];
//顏色值
GLfloat vColor[4];
//使用平面著色器
shaderManager.UseStockShader(GLT_SHADER_FLAT, mvpMatrix, vColor);
- 使用場景:在繪制圖形時,可以應(yīng)用變換(模型/投影變化)。
1.2.3 上色著色器
- 代碼編寫
//允許變化的4*4矩陣
GLfloat mvp[16];
//使用上色著色器繪制圖形
shaderManager.UseStockShader(GLT_SHADER_SHADED, mvp);
- 使用場景:在繪制圖形時,可以應(yīng)用變換(模型/投影變化),這種著色器會將顏色平滑的插入到頂點(diǎn)之間,也稱為平滑著色。
1.2.4 默認(rèn)光源著色器
- 代碼編寫
//模型矩陣
GLfloat mvMatrix[16];
//投影矩陣
GLfloat pMatrix[16];
//顏色值
GLfloat vColor[4];
//使用默認(rèn)光源(平行光)著色器繪制圖形
shaderManager.UseStockShader(GLT_SHADER_DEFAULT_LIGHT, mvMatrix, pMatrix, vColor);
- 使用場景:在繪制圖形時,可以應(yīng)用變換(模型/投影變化),這種著色器會使繪制的圖像產(chǎn)生陰影和光照的效果。
1.2.5 點(diǎn)光源著色器
- 代碼編寫
//模型矩陣
GLfloat mvMatrix[16];
//投影矩陣
GLfloat pMatrix[16];
//點(diǎn)光源的位置
GLfloat vLightPosition[3];
//顏色值
GLfloat vColor[4];
shaderManager.UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF, mvMatrix, pMatrix, vColor);
- 使用場景:在繪制圖形時,可以應(yīng)用變換(模型/投影變化),這種著色器會使繪制的圖像產(chǎn)生陰影和光照的效果,它與默認(rèn)光源著色器非常類似,區(qū)別只是光源位置可能是特定的。
1.2.6 紋理替換矩陣著色器
- 代碼編寫
//模型投影矩陣
GLfloat mvpMatrix[16];
//紋理單元
GLint nTextureUnit;
//使用紋理替換矩陣著色器
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_REPLACE, mvpMatrix, nTextureUnit);
- 使用場景:在繪制圖形時,可以應(yīng)用變換(模型/投影變化),這種著色器通過給定的模型視圖投影矩陣,使用紋理單元來進(jìn)行顏色填充,其中每個像素點(diǎn)的顏色是從紋理中獲取。
1.2.7 紋理調(diào)整著色器
- 代碼編寫
//模型投影矩陣
GLfloat mvpMatrix[16];
//顏色值
GLfloat vColor[4];
//紋理單元
GLint nTextureUnit;
//使用紋理調(diào)整著色器
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_MODULATE, mvpMatrix, vColor, nTextureUnit);
- 使用場景:在繪制圖形時,可以應(yīng)用變換(模型/投影變化),這種著色器通過給定的模型視圖投影矩陣,將一個基本色乘以一個取自紋理單元nTextureUnit的紋理,將顏色與紋理進(jìn)行顏色混合后才填充到片段中。
1.2.8 紋理光源著色器
- 代碼編寫
//模型矩陣
GLfloat mvMatrix[16];
//投影矩陣
GLfloat pMatrix[16];
//點(diǎn)光源的位置
GLfloat vLightPosition[3];
//顏色值
GLfloat vBaseColor[4];
//紋理單元
GLint nTextureUnit = 0;
//使用紋理光源著色器
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF, mvMatrix, pMatrix, vLightPosition, vBaseColor, nTextureUnit);
- 使用場景:在繪制圖形時,可以應(yīng)用變換(模型/投影變化),這種著色器通過給定的模型視圖投影矩陣,著色器將一個紋理通過漫反射照明計(jì)算進(jìn)行調(diào)整(相乘)。
2 基本圖元
2.1 常用基本圖元
基本圖元
2.2 每種圖元解釋
2.2.1 點(diǎn)(GL_POINTS)
- 點(diǎn)圖元是OpenGL中最基本的圖元類型,當(dāng)設(shè)置為此類型時,渲染頂點(diǎn)數(shù)據(jù)的時候?qū)阅J(rèn)為1的像素點(diǎn)的長度渲染傳入的頂點(diǎn)數(shù)據(jù)映射到屏幕上的坐標(biāo)位置。
- 可以使用以下種方式改變點(diǎn)的大小
//第一種:最簡單也是最常?的 4.0f,表示點(diǎn)的??
glPointSize(4.0f);
//第二種:設(shè)置點(diǎn)的??范圍和點(diǎn)與點(diǎn)之間的間隔
GLfloat sizes[2] = {2.0f,4.0f};
GLfloat step = 1.0f;
//獲取點(diǎn)??范圍和最?步?
glGetFloatv(GL_POINT_SIZE_RANGE ,sizes);
glGetFloatv(GL_POINT_GRAULARITY ,&step);
//第三種:通過使?程序點(diǎn)??模式來設(shè)置點(diǎn)??
glEnable(GL_PROGRAM_POINT_SIZE);
//第四種:這種模式下允許我們通過編程在頂點(diǎn)著?器或?何著?器中設(shè)置點(diǎn)??。著?器內(nèi)建變量:gl_PointSize,并且可以在著?器源碼直接寫
gl_PointSize = 5.0
注意:在圖形渲染之后,要將點(diǎn)的大小恢復(fù)成初始值1,這樣才不會影響其他圖形的繪制。
2.2.2 線段
- 每對頂點(diǎn)定義一個線段(GL_LINES)
- 這種類型的圖元設(shè)置,會將頂點(diǎn)數(shù)據(jù)中的點(diǎn)以兩兩結(jié)合的方式映射到屏幕上以線段的方式連接顯示
- 改變線段寬度
//設(shè)置線段寬度
glLineWidth(2.5f);
注意:在渲染線段之后,要重新設(shè)置線段寬度為默認(rèn)值1。
- 一個從第一個頂點(diǎn)依次經(jīng)過每一個后續(xù)頂點(diǎn)而繪制的線條(GL_LINE_STRIP)
- 這種類型的圖元設(shè)置,會將頂點(diǎn)數(shù)據(jù)中的點(diǎn)按照順序映射到屏幕上以一條線段的方式連接顯示
- 閉合線條(GL_LINE_LOOP)
- 與GL_LILNE_STRIP類似,但會在最后將尾部頂點(diǎn)與頭頂點(diǎn)也連接起來。
2.2.3 三角形
- 每三個頂點(diǎn)定義一個新的三角形(GL_TRIANGLES)
- 共用一條帶(strip)上的頂點(diǎn)的一組三角形(GL_TRIANGLE_STRIP)
對于很多表面或形狀而言,我們會需要繪制幾個相連的三角形,這是我們可以使用GL_TRIANGLE_STRIP圖元繪制一串相連三角形從而節(jié)省大量時間。 - 以一個圓點(diǎn)為中心呈扇形排列,共用相鄰頂點(diǎn)的一組三角形(GL_TRIANGLE_FAN)
對于很多表面或形狀而言,我們會需要繪制幾個相連的三角形,這是我們可以使用GL_TRIANGLE_FAN圖元繪制一組圍繞一個中心點(diǎn)相連的三角形。 - 使用GL_TRIANGLE_STRIP或GL_TRIANGLE_FAN繪制圖形的優(yōu)點(diǎn):
- 用前三個頂點(diǎn)指定一個三角形后,對于接下來的每個三角形,只需要再指定一個頂點(diǎn),需要繪制大量的三角形時,采用這種方式可以節(jié)省大量的程序代碼和數(shù)據(jù)存儲空間。
- 提升運(yùn)算性能和節(jié)省帶寬。更少的頂點(diǎn)意味著數(shù)據(jù)從內(nèi)存?zhèn)鬏數(shù)綀D形顯卡的速度更快,并且頂點(diǎn)著色器需要處理的次數(shù)也更少了。
-
三角形環(huán)繞方式
如下圖所示:在繪制第?個三?形時,線條是按照從V0到V1,再到V2。最后再回到V0的?個閉合三?形。 這個是沿著頂點(diǎn)順時針?向。這種順序與?向結(jié)合來指定頂點(diǎn)的?式稱為環(huán)繞。
三角形環(huán)繞方式
- 在OpenGL中,認(rèn)為具有逆時針方向環(huán)繞的多邊形為正面,這就意味著上圖左邊是正面,右邊是反面,OpenGL中,默認(rèn)是以逆時針環(huán)繞的多邊形為正面的。
- 如果想要改變這個設(shè)置可以調(diào)用glFrontFace(GL_CW);這個函數(shù),傳入?yún)?shù)為GL_CW時是告訴OpenGL以順時針環(huán)繞的多邊形為正面,傳入?yún)?shù)為GL_CCW是告訴OpenGL以逆時針環(huán)繞的多邊形為正面。
2.3 基本圖元的使用
使用GLBatch簡單容器類
方法以及其傳入?yún)?shù)解釋
//參數(shù)1:圖元
//參數(shù)2:頂點(diǎn)數(shù)
//參數(shù)3:?組或者2組紋理坐標(biāo)(可選)
void GLBatch::Begain(GLeunm primitive,GLuint nVerts,GLuint nTexttureUnints = 0);
//復(fù)制頂點(diǎn)數(shù)據(jù)(?個由3分量x,y,z頂點(diǎn)組成的數(shù)組)
void GLBatch::CopyVerterxData3f(GLfloat *vVerts);
//復(fù)制表?法線數(shù)據(jù)
void GLBatch::CopyNormalDataf(GLfloat *vNorms);
//復(fù)制顏?數(shù)據(jù)
void GLBatch::CopyColorData4f(GLfloat *vColors);
//復(fù)制紋理坐標(biāo)數(shù)據(jù)
void GLBatch::CopyTexCoordData2f(GLFloat *vTextCoords, GLuint uiTextureLayer);
//結(jié)束數(shù)據(jù)復(fù)制
void GLBatch::End(void);
//繪制圖形
void GLBatch::Draw(void);