二 OpenGL介紹及專(zhuān)有名詞解析

1. 簡(jiǎn)介

  • OpenGL(Open Graphics Library)

    是一個(gè)跨編程語(yǔ)言、跨平臺(tái)的編程圖形程序接口,接口的實(shí)現(xiàn)是由顯示設(shè)備廠(chǎng)商提供的,而且依賴(lài)于廠(chǎng)商提供的硬件設(shè)備
    也是一個(gè)標(biāo)準(zhǔn),將計(jì)算的資源抽象稱(chēng)為OpenGL對(duì)象,對(duì)資源的操作抽象為OpenGL指令。
    主要應(yīng)用于PC端處理圖形/圖像

  • OpenGL ES(OpenGLforEmbedded Systems)

    OpenGL三維圖形API的子集,針對(duì)手機(jī)、PDA和游戲主機(jī)等嵌入式設(shè)備設(shè)計(jì),去除了許多不必要和性能較低的API接口.

  • DirectX

    一個(gè)多媒體處理API(包含四大部分:顯示,聲音,輸入,網(wǎng)絡(luò)),不跨平臺(tái),只支持Windows

  • Mental

    是Apple為了解決3D渲染推出的框架.能為3D圖像提高10倍的渲染性能(主要應(yīng)用于游戲),蘋(píng)果底層渲染是由Metal 來(lái)實(shí)現(xiàn)的

    2018年蘋(píng)果棄用了OpenGLES,底層渲染遷移Metal

    棄用OpenGL原因: OpenGL是三方,蘋(píng)果需要契合你的項(xiàng)目做定制化需求和迭代,所以棄用;蘋(píng)果不可能一直把非常重要的渲染核心框架使用第三方;GPU主要用來(lái)做并發(fā)運(yùn)算,編解碼,識(shí)別,Metal前不能做自定義事情,OpenGL ES也只是自定義圖形圖像的處理,不能做項(xiàng)目?jī)?nèi)容的處理,Metal可以自定義處理

  • OpenGL與OpenCV

    OpenGL是做圖形渲染,顯示位圖;OpenCV:識(shí)別(人臉識(shí)別,身份識(shí)別,物體識(shí)別)-->OpenCV face++,與人工智能結(jié)合使用

2. 功能:實(shí)現(xiàn)圖形的底層渲染

  • 游戲場(chǎng)景/游戲人物的渲染
  • 視頻解碼后的數(shù)據(jù)渲染
  • 地圖上的數(shù)據(jù)渲染
  • 實(shí)現(xiàn)動(dòng)畫(huà)的繪制
  • 視頻加濾鏡效果

3. 本質(zhì)

  • OpenGL/OpenGL ES/Metal在任何項(xiàng)目中解決問(wèn)題的本質(zhì)就是利用GPU芯片來(lái)高效渲染圖形圖像.

4. 名詞解析

  • OpenGL 上下文(context)

    在調(diào)?OpenGL的指令之前,創(chuàng)建一個(gè)OpenGL的上下?,其實(shí)質(zhì)是一個(gè)狀態(tài)機(jī),保存了OpenGL中的各種狀態(tài)

    OpenGL的函數(shù)是面向過(guò)程的函數(shù),本質(zhì)上都是對(duì)OpenGL上下?這個(gè)龐?的狀態(tài)機(jī)中的某個(gè)狀態(tài)或者對(duì)象進(jìn)?操作。使用前把要操作的上下文設(shè)置為當(dāng)前對(duì)象。

    通過(guò)對(duì)penGL指令的封裝,可以將OpenGL的相關(guān)調(diào)?封裝成一個(gè)?向?qū)ο蟮膱D形API

    在不同線(xiàn)程中可以創(chuàng)建多個(gè)不同的上下文,上下?之間共享紋理、緩沖區(qū)等資源。

  • OpenGL 狀態(tài)機(jī)
  1. 狀態(tài)機(jī)

描述一個(gè)對(duì)象在其?命周期內(nèi)所經(jīng)歷的各種狀態(tài),狀態(tài)間的 轉(zhuǎn)變,發(fā)生轉(zhuǎn)變的動(dòng)因,條件及轉(zhuǎn)變中所執(zhí)?的活動(dòng)?;蛘哒f(shuō),狀態(tài)機(jī)是一種?為,說(shuō)明對(duì)象在其生命周期中響應(yīng)事件所經(jīng)歷的狀態(tài)序列以及對(duì)哪些狀態(tài)事件的響應(yīng)。因此具有以下特點(diǎn):

* 有記憶功能,能記住其當(dāng)前的狀態(tài)
* 可以接收輸?,根據(jù)輸入的內(nèi)容和自己的原先狀態(tài),修改自?當(dāng)前狀態(tài),并且可以有對(duì)應(yīng)輸出
* 當(dāng)進(jìn)?特殊狀態(tài)(停機(jī)狀態(tài))的時(shí)候,便不再接收輸入,停止工作;
  1. OpenGL狀態(tài)機(jī)

OpenGL可以記錄狀態(tài)(如當(dāng)前所使用的顏色、是否開(kāi)啟了混合功能等)

OpenGL可以接收輸入(當(dāng)調(diào)?用OpenGL函數(shù)的時(shí)候,可以看成OpenGL在接收輸入),如調(diào)用glColor3f,則OpenGL接收到這個(gè)輸?后會(huì)修改?己的“當(dāng)前顏色”這個(gè)狀態(tài);

OpenGL可以進(jìn)?停止?fàn)顟B(tài),不再接收輸入。在程序退出前,OpenGL總 會(huì)先停止工作

  • 渲染(Rendering)

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

  • 頂點(diǎn)數(shù)組(VertexArray)和頂點(diǎn)緩沖區(qū)(VertexBuffer)

    頂點(diǎn)是頂點(diǎn)位置數(shù)據(jù).存儲(chǔ)在內(nèi)存中。

    頂點(diǎn)數(shù)據(jù)就是圖像骨架,OpenGL中的圖像都是由圖元組成。在OpenGLES中,有3種類(lèi)型的圖元:點(diǎn)、線(xiàn)、三?形。

    所有的頂點(diǎn)數(shù)據(jù)組成的數(shù)據(jù)就是頂點(diǎn)數(shù)組。

    調(diào)用繪制?法時(shí),由內(nèi)存?zhèn)魅腠旤c(diǎn)數(shù)組,GPU會(huì)提前分配一塊顯存,將頂點(diǎn)數(shù)組數(shù)據(jù)預(yù)先傳入到顯存當(dāng)中,這部分的顯存稱(chēng)為頂點(diǎn)緩沖區(qū)(在GPU顯存中)

  • 管線(xiàn)

    在OpenGL下,顯卡在處理數(shù)據(jù)的時(shí)候按照一個(gè)固定的順序,而且嚴(yán)格按照這個(gè)順序,就像?從?根管子的一端流到另一端,這個(gè)順序是不能打破的,稱(chēng)為管線(xiàn)。

  • 固定管線(xiàn)/存儲(chǔ)著色器

    早期的OpenGL版本,封裝了很多種著?器程序塊,內(nèi)置的一段包含了光照、坐標(biāo)變換、裁剪等諸多功能的固定shader程序來(lái)完成,開(kāi)發(fā)者繪制時(shí)只需要傳?相應(yīng)的參數(shù),就能快速完成圖形的渲染,不需要關(guān)注底層實(shí)現(xiàn)原理,因此被稱(chēng)為固定管線(xiàn)。

    隨著需求的發(fā)展,固定管線(xiàn)或存儲(chǔ)著色器?法完成每?個(gè)業(yè)務(wù),對(duì)開(kāi)發(fā)者開(kāi)發(fā) 對(duì)頂點(diǎn)著色器和片元著色器編碼配置,這樣的著色器稱(chēng)為可編程著色器(直到 OpenGL ES 3.0,只?持頂點(diǎn)著色器和片段著?器這兩個(gè)著?器)

  • 著色器程序Shader

    調(diào)?繪制函數(shù)之前,需要指定?個(gè)由shader編譯成的著?器程序。

    常見(jiàn)的著色器器主要有:

      頂點(diǎn)著?器(VertexShader),
      ?段著?器 (FragmentShader)/像素著?器(PixelShader)/片元著色器,
      ?何著?器 (GeometryShader),
      曲?細(xì)分著?器(TessellationShader)
    

    OpenGL在處理shader時(shí),通過(guò)編譯、鏈接等步驟,?成著?器程序(glProgram),著?器程序同時(shí)包含了頂點(diǎn)著?器和片段著?器的運(yùn)算邏輯。

    在OpenGL進(jìn)行繪制的時(shí)候,?先由頂點(diǎn)著色器對(duì)傳?的頂點(diǎn)數(shù)據(jù)進(jìn)行運(yùn)算。再通過(guò)圖元裝配,將頂點(diǎn)轉(zhuǎn)換為圖元。然后進(jìn)?柵化,將圖元這種?量圖形,轉(zhuǎn)換為柵格化數(shù)據(jù)。最后,將柵格化數(shù)據(jù)傳入片段著?器中進(jìn)?運(yùn)算。片段著?器會(huì)對(duì)柵格化數(shù)據(jù)中的每?個(gè)像素進(jìn)行運(yùn)算,并決定像素的顏?

  • 頂點(diǎn)著?器Vertex Shader

    用來(lái)處理圖形頂點(diǎn)變換(旋轉(zhuǎn)/平移/投影等),

    用于計(jì)算頂點(diǎn)屬性(頂點(diǎn)坐標(biāo)變換、頂點(diǎn)光照運(yùn)算,將頂點(diǎn)坐標(biāo)由?身坐標(biāo)系轉(zhuǎn)換到歸一化坐標(biāo))。

    位置計(jì)算 -- 位置換算(平移/縮放/旋轉(zhuǎn))--2D投影

  • ?元著?器Fragment Shader/像素著色器

    用來(lái)處理圖形中每個(gè)像素點(diǎn)顏?計(jì)算和填充的程序

  • OpenGL著色語(yǔ)言GLSL(OpenGL Shading Language)

開(kāi)發(fā)人員自定義程序,在圖形卡的GPU (Graphic Processor Unit圖形處理單元)上執(zhí)行的, 代替了固定的渲染管線(xiàn)的一部分,使渲染管線(xiàn)中不同層次具有可編程性。比如:視圖轉(zhuǎn)換、投影轉(zhuǎn)換等。
GLSL(GL Shading Language)的著?器代碼分成2個(gè)部分: Vertex Shader(頂點(diǎn)著?器) 和Fragment Shader(片段著?器)

  • 光柵化Rasterization:把頂點(diǎn)數(shù)據(jù)轉(zhuǎn)換為片元的過(guò)程

把物體的數(shù)學(xué)描述以及與物體相關(guān)的顏色信息轉(zhuǎn)換為屏幕上?于對(duì)應(yīng)位置的像素及用于填充像素的顏色,這個(gè)過(guò)程稱(chēng)為光柵化

兩部分工作:

  1. 確定繪制區(qū)域:把物體的數(shù)學(xué)描述以及與物體相關(guān)的顏?信息轉(zhuǎn)換為屏幕上用于對(duì)應(yīng)位置的像素
  2. 填充顏色
  • 紋理:圖?

在渲染圖形時(shí)需要編碼填充圖片,這里使用的圖片,就是紋理,紋理的存儲(chǔ)格式.tag

  • 混合(Blending)

測(cè)試階段之后,像素的顏?會(huì)和幀緩沖區(qū)中顏色進(jìn)?混合形成混合色,混合的算法可以通過(guò)OpenGL的函數(shù)進(jìn)?指定。

OpenGL提供的混合算法是有限的,如果需要更加復(fù)雜的混合 算法,一般可以通過(guò)像素著?器進(jìn)?實(shí)現(xiàn),性能會(huì)比原生的混合算法差?些.

  • 變換矩陣(Transformation)
    圖形發(fā)?平移,縮放,旋轉(zhuǎn)--坐標(biāo)乘以變換矩陣.

  • 投影矩陣Projection
    用于將3D坐標(biāo)經(jīng)過(guò)投影矩陣 轉(zhuǎn)換為二維屏幕坐標(biāo)

  • 渲染上屏/交換緩沖區(qū)(SwapBuffer)

    渲染緩沖區(qū)一般映射的是系統(tǒng)的資源,比如窗口。如果將圖像直接渲染到窗?對(duì)應(yīng)的渲染緩沖區(qū),則可以將圖像顯示到屏幕上。

    如果每個(gè)窗口只有一個(gè)緩沖區(qū),那么在繪制過(guò)程中屏幕進(jìn)?了刷新,窗?可能顯示出不完整的圖像--雙緩沖區(qū)。

    常規(guī)的OpenGL程序?少都會(huì)有兩個(gè)緩沖區(qū)。顯示在屏幕上的稱(chēng)為屏幕緩沖區(qū),沒(méi)有顯示的稱(chēng)為離屏緩沖區(qū)。在一個(gè)緩沖區(qū)渲染完成之后,通過(guò)將屏幕緩沖區(qū)和離屏緩沖區(qū)交換,實(shí)現(xiàn)圖像在屏幕上的顯示。

    由于顯示器的刷新一般是逐?進(jìn)?的,因此為了防止交換緩沖區(qū)的時(shí)候屏幕上下區(qū)域的圖像分屬于兩個(gè)不同的幀,因此交換一般會(huì)等待顯示器刷新完成的信號(hào),在顯示器兩次刷新的間隔中進(jìn)行交換,這個(gè)信號(hào)就被稱(chēng)為垂直同步信號(hào),這個(gè)技術(shù)被稱(chēng)為垂直同步

    雙緩沖區(qū)要等待緩沖區(qū)交換之后再進(jìn)行下一幀的渲染,使得幀率無(wú)法完全達(dá)到硬件允許的最?水平-->三緩沖區(qū)技術(shù).

    三緩沖區(qū)技術(shù) :在等待垂直同步時(shí),來(lái)回交替渲染兩個(gè)離屏的緩沖區(qū),而垂直同步發(fā)生時(shí),屏幕緩沖區(qū)和最近渲染完成的離屏緩沖區(qū)交換,充分利用硬件性能

5. 投影方式 : 正投影和透視投影

  • 正投影 不管遠(yuǎn)近1:1進(jìn)行繪制 --->呈現(xiàn)2D效果
    函數(shù)原型:
    GLFrustum::SetOrthographic(GLfloat xMin, GLfloat xMax, GLfloat yMin, GLfloat yMax, GLfloat zMin, GLfloat zMax)
  • 透視投影 :遠(yuǎn)小近大 ---> 呈現(xiàn)3D效果

    GLFrustum類(lèi)通過(guò)setPerspective方法為構(gòu)建一個(gè)透視投影。

    函數(shù)原型:
    CLFrustum::SetPerspective(float fFov , float fAspect ,float fNear ,float fFar);

    參數(shù):

    fFov:垂直?向上的視場(chǎng)角度

    fAspect:窗口的寬度與高度的縱橫?

    fNear:近裁剪面距離

    fFar:遠(yuǎn)裁剪?距離

    縱橫? = 寬(w)/高(h)

6. 坐標(biāo)系和坐標(biāo)變換

標(biāo)準(zhǔn)化設(shè)備坐標(biāo)系:

OpenGL每次著色后,可見(jiàn)頂點(diǎn)都為標(biāo)準(zhǔn)化設(shè)備坐標(biāo)(Normalized Device Coordinate,NDC),頂點(diǎn)(x,y,z)的取值都在-1到1之間,超出這個(gè)范圍頂點(diǎn)不可見(jiàn)

從物體的坐標(biāo)變換到屏幕上的二維坐標(biāo)和像素,總共要經(jīng)歷5個(gè)不同的坐標(biāo)系:局部空間/物體空間,世界空間,觀察者空間/視覺(jué)空間,剪裁空間,屏幕空間,需要用的變換矩陣有模型,觀察,投影,具體流程如下:

image
  • 補(bǔ)充:3D圖形學(xué)中的常用坐標(biāo)系:
    世界坐標(biāo)系(所有物體都在世界坐標(biāo)系內(nèi)),
    物體坐標(biāo)系
    攝像機(jī)坐標(biāo)系
    慣性坐標(biāo)系

OpenGL只定義了裁剪坐標(biāo)系、規(guī)范化設(shè)備坐標(biāo)系和屏幕坐標(biāo)系,而局部坐標(biāo)系(模型坐標(biāo)系)、世界坐標(biāo)系和照相機(jī)坐標(biāo)系都是為了方便用戶(hù)設(shè)計(jì)而自定義的坐標(biāo)系,關(guān)系如下圖:


image

用戶(hù)自定義變換包括模型變換、視變換、投影變換,在頂點(diǎn)著色器中完成
OpenGL自動(dòng)執(zhí)行的變換包括:透視除法、視口變換,在頂點(diǎn)著色器處理后的階段完成

  • 注意: OpenGL中的相機(jī)始終位于原點(diǎn),指向-Z軸,而以相反的方式來(lái)調(diào)整場(chǎng)景中的物體,從而達(dá)到相同的觀察效果.

7. 著色器的渲染流程

image
最后編輯于
?著作權(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ù)。

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