多以概念名詞解釋和個(gè)人理解為主
快速了解圖形API
OpenGL
OpenGL(Open Graphics Library禾锤,開放式圖形庫(kù))是用于渲染2D, 3D矢量圖形的跨語(yǔ)言囤躁,跨平臺(tái)的應(yīng)用程序編程接口蓉冈。它將計(jì)算機(jī)的資源抽象稱為一個(gè)OpenGL對(duì)象烘浦,對(duì)這些資源的操作抽象為一個(gè)OpenGL指令疚脐。OpenGL被設(shè)計(jì)為只有輸出的生宛,所以它只提供渲染功能县昂。OpenGL常用于CAD、虛擬現(xiàn)實(shí)陷舅、科學(xué)可視化程序和電子游戲開發(fā)倒彰。
OpenGL ES
OpenGL ES (OpenGL for Embedded Systems) 是 OpenGL 三維圖形 API 的子集,是從 OpenGL 裁剪的定制而來(lái)的莱睁,是針對(duì)手機(jī)待讳、PDA和游戲主機(jī)等嵌入式設(shè)備而設(shè)計(jì)。
DirectX
DirectX仰剿,(Direct eXtension)是由微軟公司創(chuàng)建的多媒體編程接口耙箍。DirectX并不是一個(gè)單純的API,它是由很多個(gè)API組成的酥馍,并且只能支持Windows平臺(tái)辩昆。(作為iOS開發(fā)者作為了解即可)
Metal
Metal 是一種低層次的渲染應(yīng)用程序編程接口,提供了軟件所需的最低層旨袒,保證軟件可以運(yùn)行在不同的圖形芯片上汁针。是蘋果公司在2014年WWDC上為游戲開發(fā)者提供的新的平臺(tái)技術(shù),該技術(shù)能夠?yàn)?3D 圖像提高 10 倍的渲染性能
砚尽。Metal的優(yōu)勢(shì)就在于整合了渲染和異構(gòu)計(jì)算(和OpenGL一樣具有利用GPU加速渲染的功能 并且能和OpenCL一樣利用GPU做異構(gòu)計(jì)算) 在一個(gè)統(tǒng)一的框架上提供多種需求施无。
雖然蘋果在2018WWDC上宣布將會(huì)放棄使用OpenGL,所以目前市場(chǎng)上的大部分的應(yīng)用使用的還是OpenGL必孤,不會(huì)在短時(shí)間內(nèi)切換到Metal猾骡,所以學(xué)習(xí)OpenGL是非常有必要且重要的瑞躺,Metal更為重要!P讼搿幢哨!
OpenGL專業(yè)名詞
OpenGL 上下文(context)
在應(yīng)用程序調(diào)用OpenGL指令之前,需要?jiǎng)?chuàng)建一個(gè)OpenGL上下文嫂便,這個(gè)上下文是一個(gè)龐大的狀態(tài)機(jī)捞镰,保存著OpenGL中的各種狀態(tài),這也是OpenGL指令執(zhí)行的基礎(chǔ)毙替。OpenGL采用了客戶端-服務(wù)器模式谦絮,我們可以認(rèn)為每一個(gè)硬件GPU是個(gè)服務(wù)器桩警,每一個(gè)繪制上下文對(duì)應(yīng)于申請(qǐng)的一個(gè)客戶端,一個(gè)客戶端維護(hù)著一套狀態(tài)機(jī),如果兩個(gè)窗口分別對(duì)應(yīng)兩個(gè)不同的繪制上下文怎棱,則兩個(gè)窗口彼此狀態(tài)獨(dú)立月培。由于OpenGL上下文一個(gè)龐大的狀態(tài)機(jī)翻具,切換上下文可能會(huì)產(chǎn)生較大的系統(tǒng)資源開銷峰锁,但是不同的繪制模塊,可能需要使用完全獨(dú)立的狀態(tài)坑填,因此抛人,可以在應(yīng)用程序中創(chuàng)建多個(gè)上下文,在不同的線程中使用不同的上下文脐瑰,上下文之間共享紋理妖枚,緩沖區(qū)等資源。
OpenGL狀態(tài)機(jī)
狀態(tài)機(jī)就是一種存在于理論中的機(jī)器苍在,它具有以下的特點(diǎn):
a. 它有記憶的能力绝页,能夠記住自己當(dāng)前的狀態(tài)。
b. 它可以接收輸入寂恬,根據(jù)輸入的內(nèi)容和自己的狀態(tài)续誉,修改自己的狀態(tài),并且可以得到輸出初肉。
c. 當(dāng)它進(jìn)入某個(gè)特殊的狀態(tài)(停機(jī)狀態(tài))的時(shí)候酷鸦,它不再接收輸入,停止工作牙咏。
所以從本質(zhì)上來(lái)說(shuō)臼隔,我們的電腦是不是也可以看成一種狀態(tài)機(jī):
- 電腦的存儲(chǔ)器(內(nèi)存、硬盤等等)妄壶,可以記住電腦自己當(dāng)前的狀態(tài)(當(dāng)前安裝在電腦中的軟件摔握、保存在電腦中的數(shù)據(jù),其實(shí)都是二進(jìn)制的值丁寄,都屬于當(dāng)前的狀態(tài))氨淌。
- 電腦的輸入設(shè)備接收輸入(鍵盤輸入泊愧、鼠標(biāo)輸入、文件輸入)盛正,根據(jù)輸入的內(nèi)容和自己的狀態(tài)(主要指可以運(yùn)行的程序代碼)删咱,修改自己的狀態(tài)(修改內(nèi)存中的值),并且可以得到輸出(將結(jié)果顯示到屏幕)蛮艰。
- 當(dāng)它進(jìn)入某個(gè)特殊的狀態(tài)(關(guān)機(jī)狀態(tài))的時(shí)候,它不再接收輸入雀彼,停止工作壤蚜。
下面把OpenGL也可以看成這樣的一種機(jī)器:
(1) OpenGL可以記錄自己的狀態(tài)(比如:當(dāng)前所使用的顏色 glClearColor(1.0f,1.0f,0.0f,0.0f);、是否開啟了深度測(cè)試功能glEnable(GL_DEPTH_TEST);徊哑,等等這些都是要記錄的)
(2) OpenGL可以接收輸入(當(dāng)我們調(diào)用OpenGL函數(shù)的時(shí)候袜刷,實(shí)際上可以看成OpenGL在接收我們的輸入),根據(jù)輸入的內(nèi)容和自己的狀態(tài)莺丑,修改自己的狀態(tài)著蟹,并且可以得到輸出(比如我們調(diào)用glColor3f,則OpenGL接收到這個(gè)輸入后會(huì)修改自己的“當(dāng)前顏色”這個(gè)狀態(tài)梢莽;我們調(diào)用glRectf萧豆,則OpenGL會(huì)輸出一個(gè)矩形)
(3) OpenGL可以進(jìn)入停止?fàn)顟B(tài),不再接收輸入昏名。這個(gè)可能在我們的程序中表現(xiàn)得不太明顯涮雷,不過(guò)在程序退出前,OpenGL總會(huì)先停止工作的轻局。
渲染(Rendering)
將圖像和圖形數(shù)據(jù)轉(zhuǎn)換成3D空間圖像的操作叫做渲染(也可以理解為繪制3維圖形的時(shí)候要根據(jù)光線等外部環(huán)境對(duì)繪制與紋理質(zhì)材等內(nèi)部結(jié)構(gòu)洪鸭,生成比較真實(shí)的三維效果)這里還有一個(gè)有意思的是:“繪制”,我理解繪制應(yīng)該只是繪制基本的圖形元素仑扑,而渲染應(yīng)該更高級(jí)一點(diǎn)览爵,在繪制圖形元素的基礎(chǔ)上加上一些效果把它顯示出來(lái)。
頂點(diǎn)數(shù)組(VertexArray)和頂點(diǎn)緩沖區(qū)(VertexBuffer)
頂點(diǎn):指的是我們?cè)诶L制一個(gè)圖形的時(shí)候镇饮,它的頂點(diǎn)位置數(shù)據(jù)蜓竹,而這個(gè)數(shù)據(jù)可以存儲(chǔ)在數(shù)組中或者將其緩存到GPU的內(nèi)存中。
頂點(diǎn)數(shù)組:就是把一些頂點(diǎn)數(shù)據(jù)保存到數(shù)組中儲(chǔ)存储藐,這些數(shù)據(jù)包括:頂點(diǎn)坐標(biāo)梅肤,表面法線,RGBA顏色邑茄,輔助顏色姨蝴,顏色索引,紋理坐標(biāo)以及多邊形的邊界標(biāo)志肺缕。這樣就可以只通過(guò)一個(gè)函數(shù)調(diào)用來(lái)完成繪制左医,大大減少了函數(shù)的調(diào)用次數(shù)授帕,同時(shí)還可以避免共享頂點(diǎn)的冗余處理,提高了程序性能浮梢。
頂點(diǎn)緩沖區(qū):由于OpenGL是一個(gè)客戶端-服務(wù)器模式結(jié)構(gòu)跛十,有時(shí)從客服端傳輸數(shù)據(jù)到服務(wù)端可能會(huì)比較緩慢,所以增加了一個(gè)緩沖區(qū)對(duì)象秕硝,可以直接顯示的指定把哪些數(shù)據(jù)存儲(chǔ)到圖形服務(wù)器中芥映。
管線
管線可以理解為渲染流水線。在OpenGL下渲染圖形的時(shí)候远豺,顯卡在處理數(shù)據(jù)時(shí)是按照一個(gè)固定的順序奈偏,類似于流水線般,按照先后順序一個(gè)接一個(gè)的執(zhí)行躯护。而且必須嚴(yán)格按照這個(gè)順序惊来,不能打破。(管線棺滞,實(shí)際上指的是一堆原始圖形數(shù)據(jù)途經(jīng)一個(gè)輸送管道裁蚁,期間經(jīng)過(guò)各種變化處理最終出現(xiàn)在屏幕的過(guò)程的管理。)
固定管線(存儲(chǔ)著色器)
OpenGL在早期的時(shí)候封裝了很多種著色器程序塊內(nèi)置的一段包含了光照继准,坐標(biāo)變換枉证,剪裁等等功能的固定Shader程序來(lái)完成,幫助開發(fā)者完成圖形的渲染移必。
可編程管線
在OpenGL使用的過(guò)程中刽严,固定管線可能無(wú)法完成每一個(gè)業(yè)務(wù),這是可以將相關(guān)的部分開放成可編程避凝。
(舉個(gè)個(gè)人理解的栗子:比如說(shuō)生產(chǎn)肥皂的流水線舞萄,即管線,從原料按照流水線步驟管削,一步一步到最后生產(chǎn)出方形的倒脓,白色的肥皂塊,肥皂顏色單一含思,形狀單一崎弃,少了自由性,這就是固定管線含潘。如果在生產(chǎn)肥皂的過(guò)程中饲做,可以定制肥皂的形狀,肥皂的顏色遏弱,到最后我們就可以生產(chǎn)出各種形狀盆均,各種顏色的肥皂)
著色器程序Shader
著色器(Shader)是用來(lái)實(shí)現(xiàn)圖像渲染的,用來(lái)替代固定渲染管線的可編輯程序漱逸,即是可編程渲染管線泪姨。因此游沿,OpenGL在實(shí)際調(diào)用繪制函數(shù)之前,還需要指定一個(gè)由shader編輯成的著色器程序肮砾。
常見(jiàn)的著色器主要有:頂點(diǎn)著色器(VertexShader)诀黍,片段著色器(FragmentShader)/像素著色器(PixelShader)
,幾何著色器(GeometryShader)仗处,曲面細(xì)分著色器(TessellationShader)眯勾。最重要的是頂點(diǎn)著色器和片段著色器。
OpenGL在處理shader的時(shí)候婆誓,通過(guò)編譯吃环,鏈接等步驟,生成著色器程序(glProgram),著色器程序同時(shí)包含了頂點(diǎn)著色器和片斷著色器的運(yùn)算邏輯旷档。在OpenGL進(jìn)行渲染的時(shí)候模叙,首先由頂點(diǎn)著色器對(duì)傳入的頂點(diǎn)數(shù)據(jù)進(jìn)行計(jì)算歇拆,再通過(guò)圖元裝配鞋屈,將頂點(diǎn)轉(zhuǎn)換為圖元,然后進(jìn)行光柵化故觅,將圖元轉(zhuǎn)換為柵格化數(shù)據(jù)厂庇,最后,將柵格化數(shù)據(jù)傳入片段著色器中進(jìn)行計(jì)算输吏,片段著色器會(huì)對(duì)柵格化數(shù)據(jù)中的每一個(gè)像素進(jìn)行計(jì)算权旷,并決定像素的顏色。
頂點(diǎn)著色器(VertexShader)
頂點(diǎn)著色器一般用來(lái)處理圖形的每個(gè)頂點(diǎn)的變換(旋轉(zhuǎn)/平移/投影)實(shí)現(xiàn)了一種通用的可編程的方法操作頂點(diǎn)贯溅。頂點(diǎn)著色器是逐個(gè)頂點(diǎn)運(yùn)算的程序拄氯,即是每一個(gè)頂點(diǎn)數(shù)據(jù)都會(huì)執(zhí)行一次頂點(diǎn)著色器(并行的)。就好像每一件商品都需要經(jīng)過(guò)質(zhì)量部門的檢驗(yàn)它浅,加蓋合格章才可以出廠译柏。
片段著色器(FragmentShader)
片斷著色器:一般用來(lái)處理圖形中的每個(gè)像素點(diǎn)的顏色的填充和計(jì)算。是OpenGL中用于計(jì)算片段顏色的程序姐霍,并且逐個(gè)像素進(jìn)行運(yùn)算(并行的)鄙麦,任何一個(gè)圖形中都會(huì)有很多個(gè)像素點(diǎn),那么就會(huì)執(zhí)行很多的計(jì)算镊折,所以此時(shí)CPU就無(wú)法完成這些大量的計(jì)算胯府,此時(shí)就需要用GPU來(lái)做輔助。
GLSL(OpenGL Shading Language)
是用來(lái)在OpenGL中著色編程的語(yǔ)言恨胚,是一種面向過(guò)程的語(yǔ)言骂因,基本的語(yǔ)法和C/C++基本相同,他們是在圖形卡的GPU (Graphic Processor Unit圖形處理單元)上執(zhí)行的赃泡,代替了固定的渲染管線的一部分侣签,使渲染管線中不同層次具有可編程性塘装。比如:視圖轉(zhuǎn)換、投影轉(zhuǎn)換等等影所。GLSL的著色器代碼分成2個(gè)部分:頂點(diǎn)著色器和片段著色器蹦肴。
光柵化Rasterization
1.是指把頂點(diǎn)數(shù)據(jù)轉(zhuǎn)換為片元的過(guò)程,片元中的每一個(gè)元素對(duì)應(yīng)緩沖區(qū)中的一個(gè)像素猴娩。
2.是一種將幾何圖元轉(zhuǎn)變?yōu)槎S圖像的過(guò)程阴幌,該過(guò)程包含了兩部分內(nèi)容:1.決定窗口坐標(biāo)中的哪些整型柵格區(qū)域被基本圖元占用,2.分配一個(gè)顏色值和一個(gè)深度值到各個(gè)區(qū)域卷中,光柵化的過(guò)程就是產(chǎn)生片元矛双。
紋理
紋理是一個(gè)用來(lái)保存圖像顏色元素值的OpenGL ES緩存,可以理解為圖片/圖像蟆豫,在渲染圖形的時(shí)候需要在其編碼填充圖片议忽,為了使得場(chǎng)景更加逼真,在這里使用紋理十减。
混合(Blending)
在OpenGL中栈幸,混合通常是實(shí)現(xiàn)物體的透明度的一種技術(shù),透明就是說(shuō)一個(gè)物體并不是純色的帮辟,它的顏色是它物體本身的顏色和它背后的其他物體的顏色的不同程度的結(jié)合速址。比如我們可以混合多個(gè)顏色為一種顏色,三原色紅綠藍(lán)和在一起之后就是黑色由驹。
在測(cè)試階段之后芍锚,如果像素依然沒(méi)有被剔除,那么像素的顏色將會(huì)和幀緩沖區(qū)中顏色附著上的顏色進(jìn)行混合蔓榄。
變換矩陣(Transformation)
在圖形繪制過(guò)程中并炮,有三種變換,分別是平移甥郑,縮放逃魄,旋轉(zhuǎn)。就需要使用變換矩陣壹若。
投影矩陣(Projection)
用于將3D坐標(biāo)轉(zhuǎn)換為二維屏幕坐標(biāo)嗅钻,實(shí)際線條也將在二維坐標(biāo)下進(jìn)行繪制。
渲染上屏/交換緩沖區(qū)(SwapBuffer)
渲染緩沖區(qū)一般映射的是系統(tǒng)的資源比如窗口店展。如果將圖像直接渲染到窗口對(duì)應(yīng)的渲染緩沖區(qū)养篓,則可以將圖像顯示到屏幕上。要注意的是赂蕴,如果每個(gè)窗口只有一個(gè)緩沖區(qū)柳弄,那么在繪制過(guò)程中屏幕進(jìn)行了刷新,窗口可能顯示出不完整的圖像。
為了解決這個(gè)問(wèn)題碧注,常規(guī)的OpenGL程序至少都會(huì)有兩個(gè)緩沖區(qū)嚣伐。顯示在屏幕上的稱為屏幕緩沖區(qū),沒(méi)有顯示的稱為離屏緩沖區(qū)萍丐。在一個(gè)緩沖區(qū)渲染完成之后轩端,通過(guò)將屏幕緩沖區(qū)和離屏緩沖區(qū)交換,實(shí)現(xiàn)圖像在屏幕上的顯示逝变。
由于顯示器的刷新一般是逐行進(jìn)行的基茵,因此為了防止交換緩沖區(qū)的時(shí)候屏幕上下區(qū)域的圖像分屬于兩個(gè)不同的幀,因此交換一般會(huì)等待顯示器刷新完成的信號(hào)壳影,在顯示器兩次刷新的間隔中進(jìn)行交換拱层,這個(gè)信號(hào)就被稱為垂直同步信號(hào),這個(gè)技術(shù)被稱為垂直同步宴咧。