OpenGL ES基礎(chǔ)理論 (一) —— 緩存、幀緩存、上下文與坐標(biāo)系等

版本記錄

版本號(hào) 時(shí)間
V1.0 2018.01.10

前言

OpenGL ES這種圖形庫(kù)的使用,由于底層C函數(shù)比較多,理論也更偏向于底層和硬件GPU,所以使用起來(lái)代碼可能你都見(jiàn)過(guò),順序也知道改怎么做,但是還是多少會(huì)有點(diǎn)感覺(jué)不知道為什么這么做?具體有什么含義?接下來(lái)這幾篇我們就一起來(lái)看一下OpenGL ES基礎(chǔ)理論,一起學(xué)習(xí)一下相關(guān)的基礎(chǔ)理論。

OpenGL ES與硬件組件的關(guān)系

程序會(huì)將3D場(chǎng)景數(shù)據(jù)保存到硬件RAM中,嵌入式系統(tǒng)的中央處理單元有專門(mén)為其分配的RAM,在圖形處理的過(guò)程中,GPU也有專門(mén)為其分配的RAM,使用現(xiàn)代硬件渲染3D圖形的速度幾乎彎完全取決于不用的內(nèi)存區(qū)塊被訪問(wèn)的方式。

先看一下下圖。

OpenGL ES 是 一 種 軟 件 技 術(shù)。OpenGL ES 部分運(yùn)行在 CPU 上,部分運(yùn)行在 GPU 上。 OpenGL ES 橫跨在兩個(gè)處理器之間,協(xié)調(diào)兩個(gè)內(nèi)存區(qū)域之間的數(shù)據(jù)交換。上圖中箭頭代表了與3D渲染相關(guān)硬件組件之間的數(shù)據(jù)交換,每個(gè)箭頭也代表著一個(gè)渲染性能的瓶頸。

從一個(gè)內(nèi)存區(qū)域復(fù)制數(shù)據(jù)到另一個(gè)內(nèi)存區(qū)域速度是相對(duì)較慢的。更糟糕的是,除非非常小心,在內(nèi)存復(fù)制發(fā)生的時(shí)候 GPU 和 CPU 都不能把內(nèi)存另作它用。因此內(nèi)存區(qū)域之間的數(shù)據(jù)交換需要盡量避免。

最新的 OpenGL ES 為了支持新改進(jìn)的方法拋棄了對(duì)于舊式的低效的內(nèi)存復(fù)制操作的支持。


提供數(shù)據(jù)的最好方式 —— 緩存

OpenGL ES 為兩個(gè)內(nèi)存區(qū)域間的數(shù)據(jù)交換定義了緩存(buffers)的概念。緩存是指圖形處理器能夠控制和管理的連續(xù) RAM。程序從 CPU 的內(nèi)存復(fù)制數(shù)據(jù)到 OpenGL ES 的緩存。在 GPU 取得一個(gè)緩存的所有權(quán)以后,運(yùn)行在 CPU 中的程序理想情況下將不 再接觸這個(gè)緩存。通過(guò)控制獨(dú)占的緩存,GPU 就能夠盡可能以最有效的方式讀寫(xiě)內(nèi)存。 圖形處理器把它處理大量數(shù)據(jù)的能力異步同時(shí)地應(yīng)用到緩存上,這意味著在 GPU 使用 緩存中的數(shù)據(jù)工作的同時(shí),運(yùn)行在 CPU 中的程序可以繼續(xù)執(zhí)行。

幾乎所有的程序提供給GPU的數(shù)據(jù)都應(yīng)該放入緩存中,為緩存提供數(shù)據(jù),需要如下7個(gè)步驟:

    1. 生成(Generate): 請(qǐng)求OpenGL ES為圖形處理器控制的緩存生成一個(gè)獨(dú)一無(wú)二的標(biāo)識(shí)符。
    1. 綁定(Bind): 告訴OpenGL ES為接下來(lái)的運(yùn)算使用一個(gè)緩存。
    1. 緩存數(shù)據(jù)(Buffer Data):讓 OpenGL ES 為當(dāng)前綁定的緩存分配并初始化足 夠的連續(xù)內(nèi)存(通常是從 CPU 控制的內(nèi)存復(fù)制數(shù)據(jù)到分配的內(nèi)存)。
    1. 啟用(Enable)或者禁止(Disable):告訴 OpenGL ES 在接下來(lái)的渲染中是否使用緩存中的數(shù)據(jù)。
    1. 設(shè)置指針(Set Pointers): 告訴 Open-GL ES 在緩存中的數(shù)據(jù)的類(lèi)型和所有需 要訪問(wèn)的數(shù)據(jù)的內(nèi)存偏移值。
    1. 繪圖(Draw):告訴 OpenGL ES 使用當(dāng)前綁定并啟用的緩存中的數(shù)據(jù)渲染 整個(gè)場(chǎng)景或者某個(gè)場(chǎng)景的一部分。
    1. 刪除(Delete):告訴 OpenGL ES 刪除以前生成的緩存并釋放相關(guān)的資源。

理想情況下,每個(gè)生成的緩存都可以使用一個(gè)相當(dāng)長(zhǎng)的時(shí)間。下面看一下上面幾個(gè)步驟的OpenGL ES的C語(yǔ)言函數(shù)的實(shí)現(xiàn)。

  • glGenBuffers() — 請(qǐng)求 OpenGL ES 為圖形處理器控制的緩存生成一個(gè)獨(dú)一無(wú)二 的標(biāo)識(shí)符。
  • glBindBuffer() — 告訴 OpenGL ES 為接下來(lái)的運(yùn)算使用一個(gè)緩存。
  • glBufferData()或者 glBufferSubData() — 讓 OpenGL ES 為當(dāng)前綁定的緩存分配 并初始化足夠的連續(xù)內(nèi)存(通常是從 CPU 控制的內(nèi)存復(fù)制數(shù)據(jù)到分配的內(nèi)存)。
  • glEnableVertexAttribArray()或 者glDisableVertexAttribArray() — 告 訴 OpenGL ES 在接下來(lái)的渲染中是否使用緩存中的數(shù)據(jù)。
  • glVertexAttribPointer() — 告訴 OpenGL ES 在緩存中的數(shù)據(jù)的類(lèi)型和所有需要
    訪問(wèn)的數(shù)據(jù)的內(nèi)存偏移值。
  • glDrawArrays() 或 者 glDrawElements() — 告 訴 OpenGL ES 使 用 當(dāng) 前 綁 定 并啟用的緩存中的數(shù)據(jù)渲染整個(gè)場(chǎng)景或者某個(gè)場(chǎng)景的一部分。
  • glDeleteBuffers() — 告訴 OpenGL ES 刪除以前生成的緩存并釋放相關(guān)的資源。

幀緩存

GPU 需要知道應(yīng)該在內(nèi)存中的哪個(gè)位置存儲(chǔ)渲染出來(lái)的 2D 圖像像素?cái)?shù)據(jù)。就像 為 GPU 提供數(shù)據(jù)的緩存一樣,接收渲染結(jié)果的緩沖區(qū)叫做幀緩存(frame buffer)。程 序會(huì)像任何其他種類(lèi)的緩存一樣生成、綁定、刪除幀緩存。但是幀緩存不需要初始 化,因?yàn)殇秩局噶顣?huì)在適當(dāng)?shù)臅r(shí)候替換緩存的內(nèi)容。幀緩存會(huì)在被綁定的時(shí)候隱式開(kāi) 啟,同時(shí) OpenGL ES 會(huì)自動(dòng)地根據(jù)特定平臺(tái)的硬件配置和功能來(lái)設(shè)置數(shù)據(jù)的類(lèi)型和偏移。

可以同時(shí)存在很多幀緩存,并且可以通過(guò) OpenGL ES 讓 GPU 把渲染結(jié)果存儲(chǔ)到 任意數(shù)量的幀緩存中。但是,屏幕顯示像素要受到保存在前幀緩存(front frame buffer) 的特定幀緩存中的像素顏色元素的控制。程序和操作系統(tǒng)很少會(huì)直接渲染到前幀緩存中,因?yàn)槟菢訒?huì)讓用戶看到正在渲染中的還沒(méi)渲染完成的圖像。相反,程序和操作系統(tǒng) 會(huì)把渲染結(jié)果保存到包括后幀緩存(back frame buffer)在內(nèi)的其他幀緩存中。當(dāng)渲染后的后幀緩存包含一個(gè)完成的圖像時(shí),前幀緩存與后幀緩存幾乎會(huì)瞬間切換。后幀緩存會(huì)變成新的前幀緩存,同時(shí)舊的前幀緩存會(huì)變成后幀緩存。


OpenGL ES上下文

用于配置 OpenGL ES 的保存在特定平臺(tái)的軟件數(shù)據(jù)結(jié)構(gòu)中的信息會(huì)被封裝到一個(gè) OpenGL ES 上下文(context)中。上下文中的 信息可能會(huì)被保存在 CPU 所控制的內(nèi)存中,也可能會(huì)被保存在 GPU 所控制的內(nèi)存中。 OpenGL ES 會(huì)按需在兩個(gè)內(nèi)存區(qū)域之間復(fù)制信息,知道何時(shí)發(fā)生復(fù)制有助于程序的優(yōu)化。


OpenGL ES坐標(biāo)系

OpenGL ES 總是開(kāi)始于一個(gè)矩 形的笛卡兒坐標(biāo)系,如下圖所示。

OpenGL ES 坐標(biāo)是以浮點(diǎn)數(shù)來(lái)存儲(chǔ)的?,F(xiàn)代 GPU 對(duì)浮點(diǎn)運(yùn)算做了專門(mén)的優(yōu)化,即 使是使用其他數(shù)據(jù)類(lèi)型的頂點(diǎn)也會(huì)被轉(zhuǎn)換成浮點(diǎn)值。

后記

未完,待續(xù)~~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容