OpenGL架構(gòu)及常見圖元與簡單使用

OpenGL渲染架構(gòu)

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 ShaderFragment 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種圖元連接方式

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。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末助隧,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子滑沧,更是在濱河造成了極大的恐慌并村,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件滓技,死亡現(xiàn)場離奇詭異哩牍,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)令漂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門膝昆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人叠必,你說我怎么就攤上這事荚孵。” “怎么了纬朝?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵收叶,是天一觀的道長。 經(jīng)常有香客問我共苛,道長判没,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任隅茎,我火速辦了婚禮澄峰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘辟犀。我一直安慰自己俏竞,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著胞此,像睡著了一般臣咖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上漱牵,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天夺蛇,我揣著相機(jī)與錄音,去河邊找鬼酣胀。 笑死刁赦,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的闻镶。 我是一名探鬼主播甚脉,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼铆农!你這毒婦竟也來了牺氨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤墩剖,失蹤者是張志新(化名)和其女友劉穎猴凹,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體岭皂,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡郊霎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了爷绘。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片书劝。...
    茶點(diǎn)故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖土至,靈堂內(nèi)的尸體忽然破棺而出购对,到底是詐尸還是另有隱情,我是刑警寧澤毙籽,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布洞斯,位于F島的核電站,受9級特大地震影響坑赡,放射性物質(zhì)發(fā)生泄漏烙如。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一毅否、第九天 我趴在偏房一處隱蔽的房頂上張望亚铁。 院中可真熱鬧,春花似錦螟加、人聲如沸徘溢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽然爆。三九已至站粟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間曾雕,已是汗流浹背奴烙。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留剖张,地道東北人切诀。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像搔弄,于是被迫代替她去往敵國和親幅虑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評論 2 350