OpenGL/OpenGL ES(一)基礎(chǔ)知識(shí)

OpenGL

在開始 OpenGL ES 的學(xué)習(xí)之前,我們先來簡(jiǎn)單了解下它的由來。

計(jì)算機(jī)由 CPU、GPU、內(nèi)存、總線等構(gòu)成,全球有很多計(jì)算機(jī)制造商,導(dǎo)致市面上的計(jì)算機(jī)硬件架構(gòu)各種各樣,當(dāng)然他們都有各自的優(yōu)勢(shì),存在即合理。這些硬件會(huì)通過驅(qū)動(dòng)運(yùn)行并協(xié)作,使用驅(qū)動(dòng)的人則是軟件工程師,但總不能為不同硬件設(shè)置不同的驅(qū)動(dòng)吧,所以為了統(tǒng)一,驅(qū)動(dòng)都設(shè)置了標(biāo)準(zhǔn)接口,OpenGL 就是 GPU 驅(qū)動(dòng) 的一套標(biāo)準(zhǔn)接口,OpenGL ES 為嵌入式設(shè)備 GPU 驅(qū)動(dòng)(如手機(jī))的標(biāo)準(zhǔn)接口,OpenGL ES 全稱:OpenGL for Embedded Systems。

OpenGL API 規(guī)模龐大且復(fù)雜,OpenGL ES 的目標(biāo)是創(chuàng)建適合于受限設(shè)備的 API,為了實(shí)現(xiàn)這一目標(biāo),工作組從 OpenGL API 中刪除了冗余,比如一個(gè)操作實(shí)現(xiàn)可以用多種方法,那么就留下最實(shí)用的方法,刪除其他操作。

OpenGL 是可跨平臺(tái)使用的 API,移動(dòng)端使用 OpenGL ES 作為圖形 API,蘋果在 2014 年推出了 Metal 作為圖形 API,但它們的一些專業(yè)名詞、渲染過程等都是一樣的。

圖形API用處

可以簡(jiǎn)單的理解為實(shí)現(xiàn)了圖形的底層渲染,比如

  • 1、游戲開發(fā):游戲的場(chǎng)景、人物的渲染,這些都是由引擎去做的。
  • 2、音視頻開發(fā):視頻解碼后變成了二進(jìn)制數(shù)據(jù),利用OpenGL將這些數(shù)據(jù)渲染到屏幕。
  • 3、地圖開發(fā):地圖引擎對(duì)地圖數(shù)據(jù)的渲染
  • 4、動(dòng)畫開發(fā):實(shí)現(xiàn)動(dòng)畫的繪制
  • 5、視頻處理:視頻濾鏡開發(fā)

其實(shí)OpenGL、OpenGL ES、Metal的本質(zhì)都是利用GPU芯片來實(shí)現(xiàn)高效的渲染圖像,我們可以利用這些API操控GPU去完成我們想做的事。

OpenGL 專業(yè)名詞解析

1、OpenGL上下文(context)
  • 在OpenGL每次執(zhí)行指令前都需要?jiǎng)?chuàng)建一個(gè)上下文context,這個(gè)context是一個(gè)龐大的狀態(tài)機(jī),狀態(tài)機(jī)保存了OpenGL中的各種狀態(tài),OpenGL執(zhí)行指令的基礎(chǔ)。
  • OpenGL的函數(shù)本質(zhì)上是操作狀態(tài)機(jī)的某個(gè)狀態(tài)或?qū)ο?/strong>,它是面向過程的,我們通過對(duì)OpenGL的指令進(jìn)行封裝來達(dá)到面向?qū)ο蟮男Ч?/li>
  • OpenGL切換上下文需要很大的開銷,有時(shí)不同的繪制模塊需要完全獨(dú)立的狀態(tài)管理,所以一般會(huì)創(chuàng)建不同的上下文,在不同的線程上使用不同的上下文。上下文之間共享紋理、緩沖區(qū)等資源。
2、狀態(tài)機(jī)
  • OpenGL是基于狀態(tài)機(jī)模式的,可以理解為一種理論上的機(jī)器,它有以下特點(diǎn)

    1、記憶功能:例如當(dāng)前顏色是一個(gè)狀態(tài)變量,若把當(dāng)前顏色設(shè)置成白色或紅色,之后繪制的物體將一直使用白色或紅色,直到把當(dāng)前顏色設(shè)置成別的顏色。

    2、接收輸入:根據(jù)接收的內(nèi)容和自己的狀態(tài),修改自己的狀態(tài),例如將當(dāng)前顏色修改成黃色。

    3、當(dāng)它進(jìn)入某個(gè)特殊的狀態(tài)時(shí)(如停機(jī)狀態(tài)),它不再接收輸入,停止工作,在程序退出前,OpenGL總會(huì)先停止工作。
3、渲染

將圖形或圖像數(shù)據(jù)轉(zhuǎn)換成3D空間圖像的操作叫做渲染。

4、頂點(diǎn)數(shù)組和頂點(diǎn)緩沖區(qū)

1、頂點(diǎn)數(shù)組:把一些頂點(diǎn)數(shù)據(jù)放在頂點(diǎn)數(shù)組中。頂點(diǎn)數(shù)據(jù)即圖元,OpenGL中的圖像都是由圖元組成,有三種圖元(點(diǎn)、線、三角形),每次繪制時(shí),調(diào)用相應(yīng)的繪制函數(shù),從內(nèi)存中取出頂點(diǎn)數(shù)據(jù)傳入函數(shù)。
2、頂點(diǎn)緩沖區(qū):為了性能,我們通常會(huì)先分配一塊顯存,把頂點(diǎn)數(shù)據(jù)預(yù)存儲(chǔ)到顯存中,這樣GPU在渲染時(shí)直接從顯存讀取,速度要快很多。

5、管線

在OpenGL下渲染圖形是按步驟執(zhí)行的,這些步驟的順序不能改變,我們把這個(gè)順序稱為渲染流程,流程稱為管線。

6、固定管線/存儲(chǔ)著色器

早期OpenGL封裝了很多著色器程序塊,這些程序塊內(nèi)部包含了光照、坐標(biāo)變換、裁剪等功能,這些功能是由shader程序完成的,使得開發(fā)變得簡(jiǎn)單很多,但后期OpenGL使用的場(chǎng)景變多,固定管線或存儲(chǔ)著色器無法滿足復(fù)雜需求了,OpenGL便開放了兩個(gè)模塊可編程(這兩個(gè)模塊是渲染順序中的其他兩個(gè)步驟)。

7、著色器程序Shader

著色器是渲染3D圖形的利器,由于固定管線自身提供的3D渲染功能有限,我們需要使用shader著色器來實(shí)現(xiàn)那些豐富且復(fù)雜的3D圖形效果。

常見的著色器主要有

  • 頂點(diǎn)著色器(VertexShader)
  • 片元著色器(FragmentShader)/片段著色器/像素著色器(PixelShader)
  • 幾何著色器(GeometryShader)
  • 曲面細(xì)分著色器(TesellationShader)

目前 OpenGL ES 3.0 只支持頂點(diǎn)著色器和片元著色器可編程。

OpenGL在處理著色器時(shí),和其他編譯器一樣,需要經(jīng)過編譯、鏈接等步驟,如果我們要自定義著色器,就需要經(jīng)過這些步驟,著色器程序同時(shí)包含了頂點(diǎn)著色器和片元著色器的運(yùn)算邏輯。

OpenGL繪制過程如下:

  1. 頂點(diǎn)著色器對(duì)傳入的數(shù)據(jù)進(jìn)行運(yùn)算
  2. 裝配圖元,將頂點(diǎn)數(shù)據(jù)轉(zhuǎn)換為圖元
  3. 光柵化,將圖元轉(zhuǎn)換成柵格化數(shù)據(jù)
  4. 將光柵化的數(shù)據(jù)傳入片元著色器,片元著色器會(huì)一個(gè)個(gè)像素去計(jì)算,最終決定像素的顏色

綜上,著色器的作用就是操作GPU做計(jì)算的。

7.1、頂點(diǎn)著色器(vertexShader)

頂點(diǎn)著色器是處理頂點(diǎn)數(shù)據(jù)的旋轉(zhuǎn)、平移、投影等操作的,每個(gè)頂點(diǎn)數(shù)據(jù)都會(huì)經(jīng)過一次頂點(diǎn)著色器處理,這個(gè)處理的操作是并行的,在頂點(diǎn)著色器處理頂點(diǎn)數(shù)據(jù)過程中,無法訪問其他頂點(diǎn)數(shù)據(jù)。

通俗點(diǎn)講,頂點(diǎn)數(shù)據(jù)是基于自身坐標(biāo)系,我們可以看懂的三維坐標(biāo)系,但想渲染到屏幕上需要轉(zhuǎn)換成二維的歸一化坐標(biāo)系,頂點(diǎn)著色器就是干這個(gè)的。

7.2、片元著色器(FragmentShader)

片元著色器是處理像素點(diǎn)顏色的計(jì)算和填充,一個(gè)圖像有成千上萬個(gè)像素點(diǎn),每個(gè)像素點(diǎn)都會(huì)經(jīng)過一次片元著色器的處理,這個(gè)操作也是并行的,顯然CPU做不到這么龐大的計(jì)算(CPU更擅長(zhǎng)判斷、調(diào)度),這個(gè)過程是在GPU上執(zhí)行的。

8、GLSL(OpenGL Shading Lauguage)

這個(gè)語言和C語言類似,GLSL的著色器代碼分為頂點(diǎn)著色器和片元著色器2部分,它是在GPU上執(zhí)行的,使得渲染管線不同層次具有了可編程性。

9、光柵化

圖形在經(jīng)過頂點(diǎn)著色器轉(zhuǎn)化成歸一化的二維坐標(biāo)系,經(jīng)過光柵化處理后,轉(zhuǎn)換為片元,而片元對(duì)應(yīng)幀緩沖區(qū)中的像素點(diǎn),這個(gè)過程會(huì)分配一個(gè)顏色值和一個(gè)深度值到各個(gè)區(qū)域,光柵化的過程即將一個(gè)幾何圖元變成二維圖形

10、紋理

紋理可以簡(jiǎn)單的理解為圖片,一個(gè)png或jpg圖片要渲染到屏幕上,需要先由CPU解碼成紋理,才能交付給GPU渲染到屏幕。

11、混合(blender)

有時(shí)像素點(diǎn)沒有完全剔除,或兩個(gè)顏色疊加,會(huì)出現(xiàn)混合的情況,OpenGL有提供具有混合算法的函數(shù),但混合算法有限,如果需要復(fù)雜的混合算法,可以通過片元著色器實(shí)現(xiàn),但性能略差于OpenGL的混合算法函數(shù)。

12、矩陣
  • 變換矩陣:圖像的旋轉(zhuǎn)、平移、縮放等操作都需要使用矩陣變換。
  • 投影矩陣:將3D坐標(biāo)轉(zhuǎn)換成2D屏幕坐標(biāo)。
13、渲染上屏/幀緩沖(SwapBuffer)

要了解渲染上屏和幀緩沖,我們首先要了解屏幕上的圖像是怎么顯示的。

顯示器的刷新是逐行進(jìn)行的,渲染完一行接著渲染第二行,在整屏渲染完后會(huì)發(fā)送一個(gè)垂直信號(hào),如下圖所示。

15982699006325.png

顯示器通過視頻控制器指向的幀緩沖區(qū)讀取數(shù)據(jù)打印到屏幕,幀緩沖區(qū)一般有兩個(gè)以上,視頻控制器指向的是屏幕緩沖區(qū),未指向的是離屏緩沖區(qū)。
GPU經(jīng)過頂點(diǎn)著色器······片元著色器渲染,將數(shù)據(jù)存入離屏緩沖區(qū),等待下一次垂直信號(hào)時(shí),交換兩個(gè)幀緩沖區(qū),然后 GPU 接著渲染下一幀畫面,存入當(dāng)前的離屏緩沖區(qū)。

上面描述的就是渲染上屏和交換緩沖區(qū)的概念,請(qǐng)參照下圖理解。

15982652303103.png
14、2D坐標(biāo)系、3D坐標(biāo)系

2D坐標(biāo)系就是X軸、Y軸,3D坐標(biāo)系就是多了一個(gè)Z軸。

15、視口

視口是在窗口中用來顯示圖形的一塊區(qū)域,它可以和窗口等大,也可以比窗口小,只有繪制在視口區(qū)域的圖形才能顯示,一般都是讓視口和窗口等大,視口通過glViewPort()函數(shù)去設(shè)置。

16、正投影、透視投影

正投影:像照鏡子一樣,物體在鏡子上是等大的,不會(huì)因?yàn)檫h(yuǎn)近而放大縮小。一般平面圖形會(huì)用正投影。

透視投影:和眼睛看到的效果一樣,比如近處的人比遠(yuǎn)處的山高,一般立體圖形會(huì)用透視投影

15982641632149.jpg
17、坐標(biāo)系

規(guī)范化坐標(biāo)系區(qū)間是[-1,1]。

17.1 攝像機(jī)坐標(biāo)系

指從某個(gè)角度看向物體,起點(diǎn)為原點(diǎn),上下為y軸,左右為x軸,上后為z軸

17.2 世界坐標(biāo)系

世界坐標(biāo)系是系統(tǒng)的絕對(duì)坐標(biāo)系,在沒有建立起用戶坐標(biāo)系以前,每個(gè)物體的坐標(biāo)點(diǎn)都可以根據(jù)世界坐標(biāo)系的原點(diǎn)確定位置。

17.3 物體坐標(biāo)系

每個(gè)物體都有自己的坐標(biāo)系,是相對(duì)于自己而言的。

17.4 慣性坐標(biāo)系

慣性坐標(biāo)系和物體坐標(biāo)系的原點(diǎn)重合,但慣性坐標(biāo)系的軸平行于世界坐標(biāo)系,慣性坐標(biāo)系到世界坐標(biāo)系只需要平移,到物體坐標(biāo)系只需要旋轉(zhuǎn)。

15982643567631.jpg
17.5 總結(jié)

物體坐標(biāo)到屏幕坐標(biāo)需要經(jīng)過下列步驟

物體坐標(biāo)(模型變換)-> 世界坐標(biāo)(視變換)-> 攝像機(jī)坐標(biāo)(投影變換)-> 裁剪坐標(biāo)(透視除法)-> 規(guī)范化坐標(biāo)(視口變換)-> 屏幕坐標(biāo)

15982640146345.jpg

OpenGL中,只定義了裁剪坐標(biāo)系、規(guī)范化坐標(biāo)系和屏幕坐標(biāo)系,其他的坐標(biāo)系都是為方便用戶設(shè)計(jì)而自定義的坐標(biāo)系。

模型變換、視變換、投影變換可以根據(jù)用戶需求自行處理,在頂點(diǎn)著色器中完成
透視除法、視口變換是OpenGL自動(dòng)完成的,在頂點(diǎn)著色器處理后的階段完成。

18、著色器渲染流程

圖片從文件渲染到屏幕的過程

總結(jié)

以上就是學(xué)習(xí) OpenGL 所要具備的基礎(chǔ)知識(shí),不必完全弄明白,后面跟著 Demo 遇到不明白的術(shù)語來這里看一下,慢慢就熟悉了。

?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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