OpenGL 渲染基礎(chǔ)

一沟使、著色器

從之前的文章略水,我們應(yīng)該知道大概OpenGL的一個(gè)渲染流程流程:


Snip20201224_9.png

image.png

接下來我們?cè)俨榭匆幌翺penGL渲染架構(gòu)的簡(jiǎn)化圖


Snip20201224_11.png

就 OpenGL 而言茵瘾,客戶端是存儲(chǔ)在 CPU 存儲(chǔ)器中的酥泞,驅(qū)動(dòng)程序?qū)秩久钆c數(shù)據(jù)組合起來發(fā)給服務(wù)器執(zhí)行育特。
服務(wù)器和客戶端在功能上是異步的给猾∫哂客戶端不斷的將數(shù)據(jù)和命令組合在一起送入緩沖區(qū),緩沖區(qū)再發(fā)送到服務(wù)器執(zhí)行

Snip20201224_12.png

傳遞給著色器的屬性

  • 屬性:就是對(duì)?個(gè)頂點(diǎn)都要作出改變的數(shù)據(jù)元素敢伸。實(shí)際上扯饶,頂點(diǎn)位置本身就是一個(gè)屬性.。屬性可以是浮點(diǎn)類型详拙,整型帝际,布爾類型等稳其。
  • Uniform值:通過設(shè)置 Uniform 變量就緊接著發(fā)送一個(gè)圖元批次處理命令耿戚。Uniform 變量實(shí)際上可以無限次的使?
  • 紋理:對(duì)紋理進(jìn)行采樣和篩選蹬挺。紋理數(shù)據(jù)的作用不僅僅是表現(xiàn)圖形凄敢。很多圖形文件格式都是以無符號(hào)字節(jié)形式對(duì)顏色分量進(jìn)行存儲(chǔ)的贯要,但我們?nèi)匀豢梢栽O(shè)置浮點(diǎn)紋理讹蘑。這就是說启上,任何大型浮點(diǎn)數(shù)據(jù)塊(例如消耗資源很大的函數(shù)的大型查詢表)都可以通過這種方式傳遞給著色器

著色器

在OpenGL 核心框架中就漾,并沒提供任何內(nèi)建渲染管線,在提交一個(gè)幾何圖形進(jìn)行渲染之前痕慢,必須實(shí)現(xiàn)一個(gè)著色器尚揣。著色器由GLTools 的 C++ 類 GLShaderManager 管理

  • // GLShaderManager 的初始化
    GLShaderManager shaderManager;
    shaderManager.InitializeStockShaders();
  • 著色器的種類
單元著色器
GLShaderManager::UserStockShader(GLT_SHADER_IDENTITY,GLfloat vColor[4]);
  • 參數(shù)一:存儲(chǔ)著?色器器種類-單元著?色器器
  • 參數(shù)二:顏?
    使用場(chǎng)景:繪制默認(rèn)OpenGL 坐標(biāo)系(-1,1)下圖形. 圖形所有?片段都會(huì)以?一種顏?色填充
平面著色器
GLShaderManager::UserStockShader(GLT_SHADER_FLAT,GLfloat mvp[16],GLfloat vColor[4]);
  • 參數(shù)1: 存儲(chǔ)著?色器器種類-平?面著?色器器
  • 參數(shù)2: 允許變化的4*4矩陣
  • 參數(shù)3: 顏?

平面(Flat)著色器:將單位著色器進(jìn)行了擴(kuò)展,允許為集合圖形變換指定一個(gè) 4 x 4 的變換矩陣掖举。經(jīng)常被稱作“模型師徒投影矩陣”快骗。這種著色器只使用一個(gè)屬性 GLT_ATTRIBUTE_VERTEX。

上色著色器
GLShaderManager::UserStockShader(GLT_SHADER_SHADED,GLfloat mvp[16]);
  • 參數(shù)1: 存儲(chǔ)著?色器器種類-上?色著?色器器
  • 參數(shù)2: 允許變化的4*4矩陣

使?用場(chǎng)景: 在繪制圖形時(shí), 可以應(yīng)?用變換(模型/投影變化) 顏?色將會(huì)平滑地插?入到頂點(diǎn)之間 稱為平滑著?.

默認(rèn)光源著?色器器
GLShaderManager::UseStockShader(GLT_SHADER_DEFAULT_LIGHT, GLfoat mvMatrix[16], GLfloat pMatrix[16], GLfloat vColor[4]);
  • 參數(shù)1:默認(rèn)光源著色器
  • 參數(shù)2:模型視圖矩陣
  • 參數(shù)3:投影矩陣
  • 參數(shù)4:顏色值

使?用場(chǎng)景: 在繪制圖形時(shí), 可以應(yīng)?用變換(模型/投影變化) 這種著?色器器會(huì)使繪制的圖形產(chǎn)?生 陰影和光照的效果.

點(diǎn)光源著色器
GLShaderManager::UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF, GLfoat mvMatrix[16], GLfloat pMatrix[16], GLfloat vLightPos[3], GLfloat vColor[4]);
  • 參數(shù)1:點(diǎn)光源著色器
  • 參數(shù)2:模型視圖矩陣
  • 參數(shù)3:投影矩陣
  • 參數(shù)4:視點(diǎn)坐標(biāo)系中的光源位置
  • 參數(shù)5:顏色值

使?用場(chǎng)景: 在繪制圖形時(shí), 可以應(yīng)?用變換(模型/投影變化) 這種著?色器器會(huì)使繪制的圖形產(chǎn)?生
陰影和光照的效果.它與默認(rèn)光源著?色器器?非常類似,區(qū)別只是光源位置可能是特定的.

紋理理替換矩陣著?色器器
GLShaderManager::UserStockShader(GLT_SHADER_TEXTURE_REPLACE,GLfloat mvMatrix[16],GLint nTextureUnit);
  • 參數(shù)1: 存儲(chǔ)著?色器器種類-紋理理替換矩陣著?色器器
  • 參數(shù)2: 模型4*4矩陣
  • 參數(shù)3: 紋理理單元

使?用場(chǎng)景: 在繪制圖形時(shí), 可以應(yīng)?用變換(模型/投影變化)這種著?色器器通過給定的模 型視圖投影矩陣.使?用紋理理單元來進(jìn)?行行顏?色填充.其中每個(gè)像素點(diǎn)的顏?色是從紋理理中 獲取.

紋理調(diào)整著色器
GLShaderManager::UseStockShader(GLT_SHADER_TEXTURE_MODULATE, GLfoat mvMatrix[16], GLfloat vColor, GLint nTextureUnit);
  • 參數(shù)1: 存儲(chǔ)著?色器器種類-紋理理調(diào)整著?色器器
  • 參數(shù)2: 模型4*4矩陣
  • 參數(shù)3: 顏?色值
  • 參數(shù)4: 紋理理單元

使?用場(chǎng)景: 在繪制圖形時(shí), 可以應(yīng)?用變換(模型/投影變化)這種著?色器器通過給定的模 型視圖投影矩陣. 著?色器器將?一個(gè)基本?色乘以?一個(gè)取?自紋理理單元nTextureUnit 的紋 理理.將顏?色與紋理理進(jìn)?行行顏?色混合后才填充到?片段中.

紋理光源著色器
GLShaderManager::UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF, GLfloat mvMatrix, GLfoat mvMatrix[16], GLfloat vLightPos[3], GLfloat vBaseColor[4], GLint nTextureUnit);
  • 參數(shù)1:紋理光源著色器
  • 參數(shù)2:模型視圖矩陣
  • 參數(shù)3:投影矩陣
  • 參數(shù)4:視點(diǎn)坐標(biāo)系中的光源位置
  • 參數(shù)5:幾何圖形的基本色
  • 參數(shù)6:將要使用的紋理單元

使?用場(chǎng)景: 在繪制圖形時(shí), 可以應(yīng)?用變換(模型/投影變化)這種著?色器器通過給定的模 型視圖投影矩陣. 著?色器器將?一個(gè)紋理理通過漫反射照明計(jì)算進(jìn)?行行調(diào)整(相乘).

二塔次、基本圖元

圖元 描述
GL_POINTS 每個(gè)頂點(diǎn)在屏幕上都是單獨(dú)點(diǎn)
GL_LINES 每?一對(duì)頂點(diǎn)定義?一個(gè)線段
GL_LINE_STRIP 個(gè)從第?一個(gè)頂點(diǎn)依次經(jīng)過每?一個(gè)后續(xù)頂點(diǎn)?而繪制的線條
GL_LINE_LOOP 和GL_LINE_STRIP相同,但是最后?一個(gè)頂點(diǎn)和第?一個(gè)頂點(diǎn)連接起來了了.
GL_TRIANGLES 每3個(gè)頂點(diǎn)定義?一個(gè)新的三?角形
GL_TRIANGLE_STRIP 共?用?一個(gè)條帶(strip)上的頂點(diǎn)的?一組三?角形
GL_TRIANGLE_FAN 以?一個(gè)圓點(diǎn)為中?心呈扇形排列列,共?用相鄰頂點(diǎn)的?一組三?角形
Snip20201224_15.png
1.OpenGL點(diǎn)/線
(1)點(diǎn)

點(diǎn) 是最簡(jiǎn)單的圖像方篮。每個(gè)特定的頂點(diǎn)在屏幕上都僅僅是一個(gè)單獨(dú)的點(diǎn)。默認(rèn)的情況下励负,點(diǎn)的大小是一個(gè)像素的大小藕溅。我們可通過調(diào)用glPointSize改變默認(rèn)點(diǎn)的大小:

//  1.最簡(jiǎn)單也是最常用的 4.0f,表示點(diǎn)的大小
   glPointSize(4.0f);
    
// 2.設(shè)置點(diǎn)的大小范圍和點(diǎn)與點(diǎn)之間的間隔
GLfloat sizes[2] = {2.0f,4.0f};
GLfloat step = 1.0f;

// 獲取點(diǎn)大小范圍和最小步長(zhǎng)(增量)
glGetFloatv(GL_POINT_SIZE_RANGE,sizes);
glGetFloatv(GL_POINT_GRAULARITY,&step); 
(2)線

個(gè)線段就是2個(gè)頂點(diǎn)之間繪制的继榆。
默認(rèn)情況下巾表,線段的寬度是一個(gè)像素。改變線段唯一的方式是使用函數(shù) glLineWidth:

// 設(shè)置獨(dú)立線段寬度為1.5f;
glLineWidth(1.5f);
2 OpenGl 三角形
(1).繪制三角形

對(duì)于OpenGL光柵化最歡迎的是三角形略吨,3個(gè)頂點(diǎn)成一個(gè)三角形集币。三角形類型來自于頂點(diǎn)


Snip20201224_16.png
(2.)三角形的環(huán)繞方式
Snip20201224_17.png

在繪制第一個(gè)三角形的時(shí)候,線條是按照從v0-v1,再到v2.最后再回到v0的一個(gè)閉合三角形晋南,這個(gè)是沿著頂點(diǎn)順時(shí)針方向惠猿。這種順序與方向結(jié)合來指定頂點(diǎn)的方式成為環(huán)繞羔砾。在默認(rèn)情況下负间,OpenGl認(rèn)為具有逆時(shí)針方向環(huán)繞的多邊形為正面,這就意味著上圖左邊是正面姜凄,右邊是反面
如果想改變OpenGL這個(gè)默認(rèn)行為政溃,可以調(diào)用下面的函數(shù)

參數(shù):GL_CW | GL_CCW
GL_CCW:表示傳入的mode會(huì)選擇逆時(shí)針為前向
GL_CW:表示順時(shí)針為前向。
默認(rèn):GL_CCW态秧。逆向時(shí)針為前向董虱。
(3).OpenGl 三角形帶

對(duì)于很多表面或者形狀而言,我們會(huì)需要繪制幾個(gè)相連的三角形申鱼,這個(gè)時(shí)候我們使用GL_TRIANGLE_STRIP圖元繪制一串相連三角形愤诱,從而節(jié)省時(shí)間

Snip20201224_18.png

優(yōu)點(diǎn)

1.用前3個(gè)頂點(diǎn)指定第一個(gè)三角形之后,對(duì)于接下來的每一個(gè)三角形捐友,
只需要再指定1個(gè)頂點(diǎn)淫半,需要繪制大量的三角形時(shí),采用這種方法可以節(jié)省大量的程序代碼和數(shù)據(jù)存儲(chǔ)空間

2.提供運(yùn)算性能和節(jié)省帶寬匣砖。更少的頂點(diǎn)意味著
數(shù)據(jù)從內(nèi)存?zhèn)鬏數(shù)綀D形卡的速度更快科吭,并且頂點(diǎn)著色器需要處理的次數(shù)也更少了
(4).OpenGL 三角形扇
Snip20201224_19.png

對(duì)于很多表面或者形狀而言昏滴,我們會(huì)需要繪制幾個(gè)相連的三角形,這個(gè)時(shí)候我們可以使用GL_TRIANGLE_FAN圖元繪制一組圍繞一個(gè)中心點(diǎn)相連的三角形对人,通過4個(gè)頂點(diǎn)所產(chǎn)生的包括3個(gè)三角形的三角形扇谣殊。 第一個(gè)頂點(diǎn) V0 構(gòu)建了扇形的原點(diǎn),用前3個(gè)頂點(diǎn)指定了最初的三角形之后牺弄,后續(xù)的每個(gè)頂點(diǎn)都和原點(diǎn)(V0)以及之前緊挨著它的那個(gè)頂點(diǎn)(Vn-1)形成接下來的三角形姻几。

3.OpenGL 工具類

GLBatch 是在GLTools中包含的一個(gè)簡(jiǎn)單的容器類
使用 GLBatch 類非常簡(jiǎn)單。首先對(duì)批次進(jìn)行初始化势告,告訴這個(gè)類它代表哪種圖元鲜棠,其中包括的頂點(diǎn)數(shù),以及(可選)一組或兩組紋理坐標(biāo)培慌。

大概的操作有如下幾個(gè)方面:

  • 1.初始化
void GLBatch::Begain(GLeunm primitive,GLuint nVerts,GLuint nTexttureUnints = 0);
  • 參數(shù)1:圖元
  • 參數(shù)2:頂點(diǎn)數(shù)
  • 參數(shù)3:一組或者2組紋理坐標(biāo)(可選)
  • 2.復(fù)制表面法線
void GLBatch::CopyVertexData3f(GLfloat *vVerts);
  • 3.復(fù)制顏色數(shù)據(jù)
//復(fù)制顏色
void GLBatch::CopyColorData4f(GLfloat *vColors);
  • 4.復(fù)制紋理坐標(biāo)數(shù)據(jù)
//復(fù)制紋理坐標(biāo)
void GLBatch::CopyTexCoordData2f(GLFloat *vTextCoords,GLuint uiTextureLayer);
  • 5.結(jié)束數(shù)據(jù)復(fù)制
//結(jié)束繪制
void GLBatch::End(void);
  • 6.繪制圖形
//繪制圖形
void GLBatch::Draw(void);
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末豁陆,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子吵护,更是在濱河造成了極大的恐慌盒音,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件馅而,死亡現(xiàn)場(chǎng)離奇詭異祥诽,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)瓮恭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門雄坪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人屯蹦,你說我怎么就攤上這事维哈。” “怎么了登澜?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵阔挠,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我脑蠕,道長(zhǎng)购撼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任谴仙,我火速辦了婚禮迂求,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘晃跺。我一直安慰自己揩局,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布哼审。 她就那樣靜靜地躺著谐腰,像睡著了一般孕豹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上十气,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天励背,我揣著相機(jī)與錄音,去河邊找鬼砸西。 笑死叶眉,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的芹枷。 我是一名探鬼主播衅疙,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼鸳慈!你這毒婦竟也來了饱溢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤走芋,失蹤者是張志新(化名)和其女友劉穎绩郎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體翁逞,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡肋杖,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了挖函。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片状植。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖怨喘,靈堂內(nèi)的尸體忽然破棺而出津畸,到底是詐尸還是另有隱情,我是刑警寧澤哲思,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布洼畅,位于F島的核電站吩案,受9級(jí)特大地震影響棚赔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜徘郭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一靠益、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧残揉,春花似錦胧后、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)纸巷。三九已至,卻和暖如春眶痰,著一層夾襖步出監(jiān)牢的瞬間瘤旨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工竖伯, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留存哲,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓七婴,卻偏偏與公主長(zhǎng)得像祟偷,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子打厘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容