iOS-OpenGLES-進(jìn)階-幀緩存

這是一篇OpenGlES 系統(tǒng)學(xué)習(xí)教程柱搜,記錄自己的學(xué)習(xí)過(guò)程。
環(huán)境: Xcode10.2.1 + OpenGL ES 3.0
目標(biāo): 幀緩存
代碼已上傳github舔亭,Tutorial-08-幀緩存,你的star和fork是對(duì)我最好的支持和動(dòng)力。

概述

目前為止我們所有的渲染都是在默認(rèn)的幀緩存善绎,也就是當(dāng)前屏幕緩存。雖然這類(lèi)緩存已經(jīng)能夠滿足我們各種各樣的技術(shù)了诫尽,但是仍然有很多操作需要在不同的緩存之間大量地遷移數(shù)據(jù)禀酱。這就是幀緩存存在的意義。場(chǎng)景:如賽車(chē)的后視鏡牧嫉、王者和吃雞的小地圖等等剂跟。
默認(rèn)幀緩存是唯一可以被圖形服務(wù)器顯示系統(tǒng)所識(shí)別的幀緩存,也就是說(shuō)酣藻,我們?cè)谄聊簧峡吹降闹荒苁沁@個(gè)緩存曹洽。相比較應(yīng)用程序中創(chuàng)建的幀緩存無(wú)法被顯示器所顯示,也就出現(xiàn)了離屏渲染臊恋。

幀緩存

幀緩沖存儲(chǔ)器(Frame Buffer):簡(jiǎn)稱(chēng)幀緩存或顯存衣洁,它是屏幕所顯示畫(huà)面的一個(gè)直接映象,又稱(chēng)為位映射圖(Bit Map)或光柵抖仅。幀緩存的每一存儲(chǔ)單元對(duì)應(yīng)屏幕上的一個(gè)像素坊夫,整個(gè)幀緩存對(duì)應(yīng)一幀圖像。

  • 創(chuàng)建一個(gè)幀緩存
void glGenFramebuffers (GLsizei n, GLuint* framebuffers)
  • 綁定幀緩存
void glBindFramebuffer (GLenum target, GLuint framebuffer)
  • 刪除幀緩存
void glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers)
  • 獲取創(chuàng)建緩存狀態(tài)
let status = glCheckFramebufferStatus(GLenum(GL_FRAMEBUFFER))

if status == GL_FRAMEBUFFER_COMPLETE {
    print("fbo complete succeed width \(frameBuffer1Size.width) height \(frameBuffer1Size.height)")
} else if status == GL_FRAMEBUFFER_UNSUPPORTED {
    print("fbo unsupported")
} else {
    print("Framebuffer Error")
}

幀緩存附件
當(dāng)我們開(kāi)始渲染時(shí)撤卢,可以將渲染結(jié)果保存到以下幾個(gè)地方:

  • 創(chuàng)建圖像到顏色緩存环凿,甚至是多個(gè)顏色緩存,前提是你使用了多重渲染目標(biāo)(multiple render targets)
  • 將遮擋信息保存到深度緩存
  • 將逐像素的渲染掩碼保存到模板緩存
    這些緩存類(lèi)型每個(gè)都表示一種幀緩存的附件放吩,換句話說(shuō)智听,就是將對(duì)應(yīng)的圖像緩存(無(wú)論是剛渲染完成的,還是準(zhǔn)備讀取的),直接附加到幀緩存上到推。如下:
附件名稱(chēng) 描述
GL_COLOR_ATTACHMENTi 第i個(gè)顏色緩存考赛。i 的范圍從0(默認(rèn)顏色緩存)到GL_MAX_COLOR_ATTACHMENTS - 1
GL_DEPTH_ATTACHMENT 深度緩存
GL_STENCIL_ATTACHMENT 模板緩存
GL_DEPTH_STENCIL_ATTACHMENT 這是一種特殊的附件類(lèi)型,用于保存壓縮后的深度——模板緩存(此時(shí)需要渲染緩存的像素格式被設(shè)置為GL_DEPTH_STENCIL)

綁定幀附件

void glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) 

渲染到紋理貼圖(紋理附件)
當(dāng)我們?yōu)閹彺娼壎ㄒ粋€(gè)渲染紋理是莉测,所有的渲染命令都會(huì)寫(xiě)入到紋理上颜骤,然后我們就可以把它當(dāng)成普通紋理渲染到其他場(chǎng)景。

glGenTextures(1, &fboTextId)
glBindTexture(GLenum(GL_TEXTURE_2D), fboTextId)
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_S), GL_CLAMP_TO_EDGE)
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_T), GL_CLAMP_TO_EDGE)
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MAG_FILTER), GL_LINEAR)
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MIN_FILTER), GL_LINEAR)
// 生成紋理捣卤,數(shù)據(jù)給nil
glTexImage2D(GLenum(GL_TEXTURE_2D), 0, GL_RGBA, GLsizei(frameBuffer1Size.width), GLsizei(frameBuffer1Size.height), 0, GLenum(GL_RGBA), GLenum(GL_UNSIGNED_BYTE), nil)
glBindTexture(GLenum(GL_TEXTURE_2D), 0)

// 生成幀緩存
glGenFramebuffers(1, &frameBuffer1)
glBindFramebuffer(GLenum(GL_FRAMEBUFFER), frameBuffer1)
// 紋理關(guān)聯(lián)到幀緩存顏色附件(渲染成紋理貼圖)
glFramebufferTexture2D(GLenum(GL_FRAMEBUFFER), GLenum(GL_COLOR_ATTACHMENT0), GLenum(GL_TEXTURE_2D), fboTextId, 0)

let status = glCheckFramebufferStatus(GLenum(GL_FRAMEBUFFER))

if status == GL_FRAMEBUFFER_COMPLETE {
    print("fbo complete succeed width \(frameBuffer1Size.width) height \(frameBuffer1Size.height)")
} else if status == GL_FRAMEBUFFER_UNSUPPORTED {
    print("fbo unsupported")
} else {
    print("Framebuffer Error")
}
// 解除綁定
glBindFramebuffer(GLenum(GL_FRAMEBUFFER), 0)

渲染過(guò)程

// 渲染到紋理貼圖
glUseProgram(program1)
glBindFramebuffer(GLenum(GL_FRAMEBUFFER), frameBuffer1)

glClearColor(1.0, 1.0, 1.0, 1.0)
glClear(GLbitfield(GL_COLOR_BUFFER_BIT))

glViewport(0, 0, GLsizei(frameBuffer1Size.width), GLsizei(frameBuffer1Size.height))

glBindVertexArray(vbo1)
glActiveTexture(GLenum(GL_TEXTURE0))
glBindTexture(GLenum(GL_TEXTURE_2D), textId)
glUniform1i(glGetUniformLocation(program1,"u_Texture"), 0)
glDrawArrays(GLenum(GL_TRIANGLES), 0, 6)

// 渲染到默認(rèn)幀緩存
glUseProgram(program)
glBindFramebuffer(GLenum(GL_FRAMEBUFFER), frameBuffer)

glClearColor(0.0, 1.0, 1.0, 1.0)
glClear(GLbitfield(GL_COLOR_BUFFER_BIT))

glViewport(0, 0, GLsizei(frame.size.width), GLsizei(frame.size.height))

glBindVertexArray(vbo)
glActiveTexture(GLenum(GL_TEXTURE1))
glBindTexture(GLenum(GL_TEXTURE_2D), fboTextId)
glUniform1i(glGetUniformLocation(program1,"u_Texture"), 1)
glDrawArrays(GLenum(GL_TRIANGLES), 0, 6)

presentContex?.presentRenderbuffer(Int(GL_RENDERBUFFER))

注:可以前往demo查看細(xì)節(jié)

效果

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末忍抽,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子董朝,更是在濱河造成了極大的恐慌鸠项,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件子姜,死亡現(xiàn)場(chǎng)離奇詭異祟绊,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)哥捕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)久免,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人扭弧,你說(shuō)我怎么就攤上這事阎姥。” “怎么了鸽捻?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵呼巴,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我御蒲,道長(zhǎng)衣赶,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任厚满,我火速辦了婚禮府瞄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘碘箍。我一直安慰自己遵馆,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布丰榴。 她就那樣靜靜地躺著货邓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪四濒。 梳的紋絲不亂的頭發(fā)上换况,一...
    開(kāi)封第一講書(shū)人閱讀 49,031評(píng)論 1 285
  • 那天职辨,我揣著相機(jī)與錄音,去河邊找鬼戈二。 笑死舒裤,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的觉吭。 我是一名探鬼主播惭每,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼亏栈!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起宏赘,我...
    開(kāi)封第一講書(shū)人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤绒北,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后察署,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體闷游,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年贴汪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了脐往。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡扳埂,死狀恐怖业簿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情阳懂,我是刑警寧澤梅尤,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站岩调,受9級(jí)特大地震影響巷燥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜号枕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一缰揪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧葱淳,春花似錦钝腺、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至坑傅,卻和暖如春僵驰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工蒜茴, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留星爪,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓粉私,卻偏偏與公主長(zhǎng)得像顽腾,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子诺核,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

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