OpenGL渲染架構(gòu)
上圖是根據(jù)自己的學(xué)習(xí)跟理解紊服,簡單繪制的一張結(jié)構(gòu)圖秧了。從上圖可以看出我們通過OpenGL API 來間接操作GPU
通道(傳遞數(shù)據(jù)的方式)
- attribute 屬性 (只能直接傳遞到頂點(diǎn)著色器,不能直接傳遞到片元著色器,需要間接訪問)
顏色數(shù)據(jù)
頂點(diǎn)數(shù)據(jù)
紋理坐標(biāo)
光柵法線 - uniform 值 (相對固定昵骤,可以直接傳遞到片元著色器/頂點(diǎn)著色器)
渲染矩陣(比如YUV->RGB 的轉(zhuǎn)化矩陣) - texture Data (可以傳遞到頂點(diǎn)著色器/片元著色器)
濾鏡
渲染圖形
像素填充->顏色填充
實(shí)際開發(fā)中我們可編程的部分是Vertex Shader
和Fragment Shader
,而Primitive Assembly
部分由OpenGL內(nèi)部完成,無法干預(yù)师痕。
正投影與透視投影
正投影:通常用來渲染2D效果,平行投影,1:1繪制,
透視投影:通常用來渲染3D效果,空間感(遠(yuǎn)小近大)
使用GLFrustum
類來創(chuàng)建投影方式:
/// 創(chuàng)建正投影矩陣
/// @param xMin x軸最小值
/// @param xMax x軸最大值
/// @param yMin y軸最小值
/// @param yMax y軸最大值
/// @param zMin z軸最小值
/// @param zMax z軸最大值
void SetOrthographic(GLfloat xMin, GLfloat xMax, GLfloat yMin, GLfloat yMax, GLfloat zMin, GLfloat zMax)
/// 創(chuàng)建透視投影矩陣
/// @param fFov 垂直?方向上的視場?角度
/// @param fAspect 窗?口的寬度與?高度的縱橫?(w/h)
/// @param fNear 近裁剪?面距離
/// @param fFar 遠(yuǎn)裁剪?面距離
void SetPerspective(float fFov, float fAspect, float fNear, float fFar)
GLShaderManager存儲著色管理器
GLShaderManager
:內(nèi)部封裝了很多著色器会通,通過枚舉值及對應(yīng)的參數(shù)來供開發(fā)者使用,我們不需要考慮著色器內(nèi)部實(shí)現(xiàn)且無法自定義性雄,只能在應(yīng)用層操作没卸。
初始化GLShaderManager
GLShaderManager shaderManager;
shaderManager.InitializeStockShaders();
使用單元著色器
GLShaderManager::UserStockShader(GLT_SHADER_IDENTITY,GLfloat vColor[4]);
**UserStockShader()**
// nShaderID 著色器名稱(ID)
// id 對應(yīng) 所需的參數(shù)
GLint UseStockShader(GLT_STOCK_SHADER nShaderID, ...);
其它著色器列舉(主要是看下不同Shader_ID下對應(yīng)的參數(shù))
//單元著色器
GLShaderManager::UserStockShader(GLT_SHADER_IDENTITY,GLfloat vColor[4]);
//平面著色器
GLShaderManager::UserStockShader(GLT_SHADER_FLAT,GLfloat mvp[16],GLfloat vColor[4]);
//上色著色器
GLShaderManager::UserStockShader(GLT_SHADER_SHADED,GLfloat mvp[16]);
//默認(rèn)光源著色器
GLShaderManager::UserStockShader(GLT_SHADER_DEFAULT_LIGHT,GLfloat mvMatrix[16],GLfloat pMatrix[16],GLfloat vColor[4]);
//點(diǎn)光源著色器
GLShaderManager::UserStockShader(GLT_SHADER_POINT_LIGHT_DIEF,GLfloat mvMatrix[16],GLfloat pMatrix[16],GLfloat vLightPos[3],GLfloat vColor[4]);
//紋理替換矩陣著色器
GLShaderManager::UserStockShader(GLT_SHADER_TEXTURE_REPLACE,GLfloat mvMatrix[16],GLint nTextureUnit);
//紋理調(diào)整著色器
GLShaderManager::UserStockShader(GLT_SHADER_TEXTURE_MODULATE,GLfloat mvMatrix[16],GLfloat vColor[4],GLint nTextureUnit);
//紋理光源著色器
GLShaderManager::UserStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIEF,G Lfloat mvMatrix[16],GLfloat pMatrix[16],GLfloat vLightPos[3],GLfloat vBaseColor[4],GLint nTextureUnit);
......
確實(shí)挺色的????
OpenGL圖元
圖元即基本圖形元素,是任何一個圖形表達(dá)都是由若干不同的點(diǎn)秒旋、線约计、面圖案或相同的圖案循環(huán)組合而成的。這些點(diǎn)迁筛、線煤蚌、面圖案即為基本圖形元素,簡稱圖元。OpenGL中通過不過的圖元來呈現(xiàn)不同的圖像尉桩。
9種圖元連接方式
圖元 | 描述 |
---|---|
GL_POINTS | 每個頂點(diǎn)在屏幕上都是獨(dú)立的點(diǎn) |
GL_LINES | 每兩個頂點(diǎn)定義一條線段,兩兩連接 |
GL_LINES_STRIP | 將每一個頂點(diǎn)依次連接的線 |
GL_LINE_LOOP | 將每一個頂點(diǎn)依次連接的閉合線段 |
GL_TRIANGLES | 每3個頂點(diǎn)定義一個三角形 |
GL_TRIANGLE_STRIP | 共用一個邊上的頂點(diǎn)的一組三角形 |
GL_TRIANGLE_FAN | 以一個頂點(diǎn)作為原點(diǎn)設(shè)為中心呈扇形排列,共用相鄰頂點(diǎn)的一組三角形 |
- 設(shè)置點(diǎn)的大小
glPointSize(4.0f);
- 設(shè)置線寬
glLineWidth(2.5f);
使用
在OpenGL中通過GLBatch
(是GLTools中包含的簡單容器類)批次類來設(shè)置圖元連接方式和組裝頂點(diǎn)數(shù)據(jù):
void GLBatch::Begain(GLeunm primitive,GLuint nVerts,GLuint nTexttureUnints = 0);
參數(shù)1:圖元
參數(shù)2:頂點(diǎn)數(shù) 參數(shù)3:?一組或者2組紋理理坐標(biāo)(可選)
//復(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);
- 使用
GL_POINTS
圖元方式
GLfloat vCoast[9] = {
3,3,0,
0,3,0,
3,0,0
};
//GLBatch四部曲:Begin->Copy->End->Draw
//用點(diǎn)的形式
pointBatch.Begin(GL_POINTS, 3);
pointBatch.CopyVertexData3f(vCoast);
pointBatch.End();
這里省略了對其它圖元的舉例......具體看代碼筒占。
繪制
// Clear the window with current clearing color 清空當(dāng)前緩存區(qū)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
//壓棧(記錄狀態(tài))
modelViewMatrix.PushMatrix();
M3DMatrix44f mCamera;
cameraFrame.GetCameraMatrix(mCamera);
//矩陣乘以矩陣堆棧的頂部矩陣,相乘的結(jié)果隨后簡存儲在堆棧的頂部
modelViewMatrix.MultMatrix(mCamera);
M3DMatrix44f mObjectFrame;
//只要使用 GetMatrix 函數(shù)就可以獲取矩陣堆棧頂部的值蜘犁,這個函數(shù)可以進(jìn)行2次重載翰苫。用來使用GLShaderManager 的使用≌獬龋或者是獲取頂部矩陣的頂點(diǎn)副本數(shù)據(jù)
objectFrame.GetMatrix(mObjectFrame);
//矩陣乘以矩陣堆棧的頂部矩陣奏窑,相乘的結(jié)果隨后簡存儲在堆棧的頂部
modelViewMatrix.MultMatrix(mObjectFrame);
/* GLShaderManager 中的Uniform 值——平面著色器
參數(shù)1:平面著色器
參數(shù)2:運(yùn)行為幾何圖形變換指定一個 4 * 4變換矩陣
--transformPipeline.GetModelViewProjectionMatrix() 獲取的
GetMatrix函數(shù)就可以獲得矩陣堆棧頂部的值
參數(shù)3:顏色值(黑色)
*/
shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBlack);
//設(shè)置點(diǎn)的大小
glPointSize(4.0f);
pointBatch.Draw();
glPointSize(1.0f);
//還原到以前的模型視圖矩陣(單位矩陣)移除狀態(tài)
modelViewMatrix.PopMatrix();
// 進(jìn)行緩沖區(qū)交換,顯示到屏幕
glutSwapBuffers();
矩陣
modelViewMatrix
:模型視圖矩陣
projectionMatrix
:投影矩陣
transformPipeline
:變換管道
//設(shè)置需要相乘的矩陣
transformPipeline.SetMatrixStacks(GLMatrixStack &mModelView, GLMatrixStack &mProjection)
//返回相乘后的結(jié)果矩陣
M3DMatrix44f transformPipeline.GetModelViewProjectionMatrix()
從GLFrame
中獲取矩陣:
GLFrame cameraFrame;
GLFrame objectFrame;
//獲取觀察者矩陣
M3DMatrix44f mCamera;
cameraFrame.GetCameraMatrix(mCamera);
//獲取投影矩陣
M3DMatrix44f mObjectFrame;
objectFrame.GetMatrix(mObjectFrame);
矩陣的作用:讓一個數(shù)據(jù)集做批量處理的方式屈扎。比如我們的例子中讓頂點(diǎn)數(shù)據(jù)通過一個矩陣做一些批量的修改良哲;比如一個YUV * 矩陣 = RGBA。