iOS實現(xiàn)圖形編程可以使用三種API(UIKIT想际、Core Graphics拧粪、OpenGL ES及GLKit)双饥。
這些api包含的繪制操作都在一個圖形環(huán)境中進行繪制硫麻。一個圖形環(huán)境包含繪制參數(shù)和所有的繪制需要的設備特定信息,包括屏幕圖形環(huán)境官硝、offscreen 位圖環(huán)境和PDF圖形環(huán)境矗蕊,用來在屏幕表面、一個位圖或一個pdf文件中進行圖形和圖像繪制氢架。在屏幕圖形環(huán)境中進行的繪制限定于在一個UIView類或其子類的實例中繪制傻咖,并直接在屏幕顯示,在offscreen位圖或PDF圖形環(huán)境中進行的繪制不直接在屏幕上顯示岖研。
一卿操、UIKIT API
UIKIT是一組Objective-C API,為線條圖形缎玫、Quartz圖像和顏色操作提供Objective-C 封裝硬纤,并提供2D繪制、圖像處理及用戶接口級別的動畫赃磨。
UIKIT包括UIBezierPath(繪制線筝家、角度、橢圓及其它圖形)邻辉、UIImage(顯示圖像)溪王、UIColor(顏色操作)腮鞍、UIFont和UIScreen(提供字體和屏幕信息)等類以及在位圖圖形環(huán)境、PDF圖形環(huán)境上進行繪制和 操作的功能等, 也提供對標準視圖的支持莹菱,也提供對打印功能的支持移国。
在UIKIT中UIView類本身在繪制時自動創(chuàng)建一個圖形環(huán)境(對應Core Graphics層的CGContext類型)作為當前的圖形繪制環(huán)境。在繪制時可以調(diào)用UIGraphicsGetCurrentContext 函數(shù)獲得當前的圖形環(huán)境道伟。
二迹缀、Core Graphics 與Quartz 2D API
Core Graphics是一套C-based API, 支持向量圖形蜜徽,線祝懂、形狀、圖案拘鞋、路徑砚蓬、剃度、位圖圖像和pdf 內(nèi)容的繪制盆色。
Quartz 2D 是Core Graphics中的2D 繪制呈現(xiàn)引擎灰蛙。Quartz是資源和設備無關(guān)的,提供路徑繪制,anti-aliased呈現(xiàn)隔躲,剃度填充圖案摩梧,圖像,透明繪制和透明層宣旱、遮蔽和陰影障本、顏色管理,坐標轉(zhuǎn)換响鹃,字體、offscreen呈現(xiàn)案训、pdf文檔創(chuàng)建买置、顯示和分析等功能。
Quartz 2D能夠與所有的圖形和動畫技術(shù)(如Core Animation, OpenGL ES, 和 UIKit 等)一起使用强霎。
Quartz采用paint模式進行繪制忿项。
Quartz 中使用的圖形環(huán)境也由一個類CGContext表示。
在Quartz 中可以把一個圖形環(huán)境作為一個繪制目標城舞。當使用Quartz 進行繪制時轩触,所有設備特定的特性被包含在你使用的特定類型的圖形環(huán)境中,因此通過給相同的圖像操作函數(shù)提供不同的圖像環(huán)境你就能夠畫相同的圖像到不同的設備上家夺,因此做到了圖像繪制的設備無關(guān)性脱柱。
Quartz 為應用提供如下幾個圖形環(huán)境:
1)位圖圖形環(huán)境,用來創(chuàng)建一個位圖拉馋。
使用函數(shù)CGBitmapContextCreate來創(chuàng)建榨为。
2)PDF圖形環(huán)境惨好,用來創(chuàng)建一個pdf文件。
Quartz 2D API提供了兩個函數(shù)來創(chuàng)建一個PDF圖形環(huán)境:
CGPDFContextCreateWithURL随闺,帶有一個作為pdf 輸出的位置的Core Foundation URL來創(chuàng)建一個pdf 圖形環(huán)境日川。
CGPDFContextCreate, 當想PDF 輸出到一個data consumer時使用該函數(shù)。
3) 窗口圖形環(huán)境矩乐,用來在一個窗口上進行繪制龄句。
4) 層環(huán)境(CGLayer) ,是一個與另一個圖形環(huán)境關(guān)聯(lián)的offscreen繪制目標散罕,使用層環(huán)境的目的是為了優(yōu)化繪制層到創(chuàng)建它的圖形環(huán)境的性能分歇。層環(huán)境能夠比位圖圖形環(huán)境提供更好的offscreen繪制性能。
Quartz提供的主要類包括:
CGContext:表示一個圖形環(huán)境笨使;
CGPath:使用向量圖形來創(chuàng)建路徑卿樱,并能夠填充和stroke;
CGImage:用來表示位圖硫椰;
CGLayer:用來表示一個能夠用于重復繪制和offscreen繪制的繪制層繁调;
CGPattern:用來表示Pattern,用于重復繪制靶草;
CGShading和 CGGradient:用于繪制剃度蹄胰;
CGColor 和 CGColorSpace;用來進行顏色和顏色空間管理奕翔;
CGFont, 用于繪制文本裕寨;
CGPDFContentStream、CGPDFScanner派继、CGPDFPage宾袜、CGPDFObject,CGPDFStream, CGPDFString等用來進行pdf文件的創(chuàng)建、解析和顯示驾窟。
三庆猫、OpenGL ES和GLKit
OpenGL ES是一套多功能開放標準的用于嵌入系統(tǒng)的C-based的圖形庫,用于2D和3D數(shù)據(jù)的可視化绅络。OpenGL被設計用來轉(zhuǎn)換一組圖形調(diào)用功能到底層圖形硬件(GPU)月培,由GPU執(zhí)行圖形命令,用來實現(xiàn)復雜的圖形操作和運算恩急,從而能夠高性能杉畜、高幀率利用GPU提供的2D和3D繪制能力。
OpenGL ES規(guī)范本身不定義繪制表面和繪制窗口衷恭,因此ios為了使用它必須提供和創(chuàng)建一個OpenGLES 的呈現(xiàn)環(huán)境此叠,創(chuàng)建和配置存儲繪制命令結(jié)果的framebuffer 及創(chuàng)建和配置一個或多個呈現(xiàn)目標。
在 iOS中使用EAGL提供的EAGLContext類 來實現(xiàn)和提供一個呈現(xiàn)環(huán)境匾荆,用來保持OpenGLES使用到的硬件狀態(tài)拌蜘。 EAGL是一個Objective-C API杆烁,提供使OpenGL ES與Core Animation和UIKIT集成的接口。
在調(diào)用任何OpenGLES 功能之前必須首先初始化一個EAGLContext 對象简卧。
每一個iOS應用的每一個線程都有一個當前context兔魂,在調(diào)用OpenGLES函數(shù)時,使用或改變此context中的狀態(tài)举娩。
EAGLContext 的類方法setCurrentContext:用來設置當前線程的當前context析校。EAGLContext 的類方法currentContext 返回當前線程的當前context。在切換相同線程的兩個上下文之前铜涉,必須調(diào)用glFlush函數(shù)來確保先前已提交的命令被提交到圖形硬件中智玻。
可以采用不同的方式使用OpenGL ES以便呈現(xiàn)OpenGL ES內(nèi)容到不同的目標:GLKit和CAEAGLLayer。
為了創(chuàng)建全屏幕的視圖或使OpenGL ES內(nèi)容與UIKit視圖集成芙代,可以使用GLKit吊奢。在使用GLKit時,GLKit提供的類GLKView類本身實現(xiàn)呈現(xiàn)目標及創(chuàng)建和維護一個framebuffer纹烹。
為了使OpenGL ES內(nèi)容作為一個Core Animation層的部分內(nèi)容時页滚,可以使用CAEAGLLayer 作為呈現(xiàn)目標,并需要另外創(chuàng)建framebuffer以及自己實現(xiàn)和控制整個繪制流程铺呵。
GLKit是一組Objective-C 類裹驰,為使用OpenGL ES 提供一個面向?qū)ο蠼涌冢脕砗喕疧penGL ES應用的開發(fā)片挂。GLKit支持四個3D應用開發(fā)的關(guān)鍵領域:
1) GLKView 和GLKViewController類提供一個標準的OpenGLES視圖和相關(guān)聯(lián)的呈現(xiàn)循環(huán)幻林。GLKView可以作為OpenGLES內(nèi)容的呈現(xiàn)目標,GLKViewController提供內(nèi)容呈現(xiàn)的控制和動畫音念。視圖管理和維護一個framebuffer沪饺,應用只需在framebuffer進行繪畫即可。
2)GLKTextureLoader 為應用提供從iOS支持的各種圖像格式的源自動加載紋理圖像到OpenGLES 圖像環(huán)境的方式闷愤,并能夠進行適當?shù)霓D(zhuǎn)換随闽,并支持同步和異步加載方式。
3)數(shù)學運算庫肝谭,提供向量、矩陣蛾扇、四元數(shù)的實現(xiàn)和矩陣堆棧操作等OpenGL ES 1.1功能攘烛。
4)Effect效果類提供標準的公共著色效果的實現(xiàn)。能夠配置效果和相關(guān)的頂點數(shù)據(jù)镀首,然后創(chuàng)建和加載適當?shù)闹鞣厥LKit 包括三個可配置著色效果類:GLKBaseEffect實現(xiàn)OpenGL ES 1.1規(guī)范中的關(guān)鍵的燈光和材料模式, GLKSkyboxEffect提供一個skybox效果的實現(xiàn), GLKReflectionMapEffect 在GLKBaseEffect基礎上包括反射映射支持。
使用GLKView和OpenGLES進行繪制過程:
1)創(chuàng)建一個GLKView 對象
GLKView 對象可以編程或使用Interface Builder來創(chuàng)建和配置更哄。
在采用編程方式時芋齿,首先創(chuàng)建一個context然后調(diào)用initWithFrame:context:方法腥寇。
使用Interface Builder方式時,在從storyboard加載一個GLKView后觅捆,創(chuàng)建一個context和設置它作為視圖的context屬性.
在iOS中GLKit的使用需要創(chuàng)建OpenGL ES 2.0以上的圖形環(huán)境context赦役。
GLKit視圖自動創(chuàng)建和配置它所有的OpenGLES framebuffer對象和renderbuffers,可以通過修改視圖的drawable屬性來控制這些對象的屬性栅炒。
2)繪制OpenGL內(nèi)容(發(fā)布繪制命令)
使用GLKit視圖繪制OpenGL內(nèi)容需要三個子步驟:準備OpenGLES基礎掂摔;發(fā)布繪制命令;呈現(xiàn)顯示內(nèi)容到Core Animation赢赊。 GLKit類本身已經(jīng)實現(xiàn)了第一個和第三個步驟乙漓,用戶只需實現(xiàn)第二個步驟,在視圖的方法drawRect或視圖的代理對象的glkView:drawInRect:中調(diào)用適當?shù)腛penGLES繪制命令進行內(nèi)容繪制释移。
GLKViewController類維護一個animation 呈現(xiàn)循環(huán)(包含兩個方法update和display)叭披,用來實現(xiàn)連續(xù)的動畫復雜的場景。
animation 呈現(xiàn)循環(huán)的交替速率由GLKViewController的屬性framesPerSecond 指示玩讳,并使用preferredFramesPerSecond 屬性來修改它涩蜘。
四、其它圖形編程相關(guān)API
1)Core Animation
Core Animation是一套Objective-C API锋边,實現(xiàn)了一個高性能的復合引擎皱坛,并提供一個簡單易用的編程接口,給用戶UI添加平滑運動和動態(tài)反饋能力豆巨。
Core Animation 是 UIKit實現(xiàn)動畫和變換的基礎剩辟,也負責視圖的復合功能。使用Core Animation可以實現(xiàn)定制動畫和細粒度的動畫控制往扔,創(chuàng)建復雜的贩猎、支持動畫和變換的layered 2D視圖。
Core Animation不屬于繪制系統(tǒng)萍膛,但它是以硬件復合和操作顯示內(nèi)容的基礎設施吭服。這個基礎設施的核心是layer對象,用來管理和操作顯示內(nèi)容蝗罗。在ios 中每一個視圖都對應Core Animation的一個層對象艇棕,與視圖一樣,層之間也組織為層關(guān)系樹串塑。一個層捕獲視圖內(nèi)容為一個被圖像硬件容易操作的位圖沼琉。在多數(shù)應用中層作為管理視圖的方式使用,但也可以創(chuàng)建獨立的層到一個層關(guān)系樹中來顯示視圖不夠支持的顯示內(nèi)容桩匪。
OpenGL ES的內(nèi)容也可以與Core Animation內(nèi)容進行集成打瘪。
為了使用Core Animation實現(xiàn)動畫,可以修改層的屬性值來觸發(fā)一個action對象的執(zhí)行,不同的action對象實現(xiàn)不同的動畫闺骚。
Core Animation 提供了一下一組應用可以采用的類來提供對不同動畫類型的支持:
CAAnimation是一個抽象公共基類彩扔,CAAnimation采用CAMediaTiming 和CAAction協(xié)議為動畫提供時間(如周期、速度僻爽、重復次數(shù)等)和action行為(啟動虫碉、停止等)。
CAPropertyAnimation是 CAAnimation的抽象子類进泼,為動畫提供一個由一個key路徑規(guī)定的層屬性的支持蔗衡;
CABasicAnimation 是CAPropertyAnimation的具體子類,為一個層屬性提供簡單插入能力乳绕。
CAKeyframeAnimation也是CAPropertyAnimation的具體子類绞惦,提供key幀動畫支持。
CATransition是CAAnimation的具體子類洋措,提供影響整個層內(nèi)容的事物效果济蝉。
CAAnimationGroup也是CAAnimation的子類,允許動畫對象組合到一起并同時運行菠发。
2)Image I/O
Image I/O 提供讀寫多數(shù)格式圖像文件的數(shù)據(jù)的接口王滤。主要包括圖像源CGImageSourceRef和圖像目標CGImageDestinationRef兩個類。
3)Sprite Kit
Sprite Kit建立于OpenGL ES之上滓鸠,Sprite Kit使用圖形硬件來有效的呈現(xiàn)動畫幀雁乡,因此可以高幀率地動畫和呈現(xiàn)任意的2D紋理圖像或游戲sprite,呈現(xiàn)的內(nèi)容包括sprites糜俗、文本踱稍、CGPath形狀、視頻等悠抹。
在Sprite Kit中動畫和呈現(xiàn)由一個SKView視圖對象執(zhí)行珠月。游戲的內(nèi)容組織為以SKScene對象表現(xiàn)的一個個場景。一個場景包含要呈現(xiàn)的sprites和其它內(nèi)容楔敌,一個場景也實現(xiàn)每個幀關(guān)聯(lián)的邏輯和內(nèi)容處理啤挎。
在同一時刻,一個SKView視圖只呈現(xiàn)一個場景卵凑,在場景呈現(xiàn)時庆聘,場景關(guān)聯(lián)的動畫和幀關(guān)聯(lián)的邏輯被自動執(zhí)行。在切換場景時使用SKTransition 類來執(zhí)行兩個場景間的動畫勺卢。
4)SceneKit
SceneKit是一個使用3D圖形技術(shù)實現(xiàn)的Objective-C 框架掏觉,包含一個高性能的呈現(xiàn)引擎和一個高級的描述性API≈德可以利用該框架創(chuàng)建簡單的游戲和界面豐富的用戶UI,使用SceneKit僅需要使用描述性API描述你的場景的內(nèi)容(如幾何形狀织盼、材料杨何、燈光和攝像等)和你想在那些內(nèi)容上要執(zhí)行的行動或動畫即可酱塔。
SceneKit的內(nèi)容組織為由節(jié)點組成的樹形結(jié)構(gòu),稱為scene graph危虱。一個場景包含一個根節(jié)點羊娃,定義場景的坐標空間,其它節(jié)點定義場景的可視內(nèi)容埃跷。SceneKit在GPU上呈現(xiàn)每一幀之前在一個視圖上顯示場景蕊玷、處理scene graph和執(zhí)行動畫處理。
SceneKit包含的主要類:
SCNView & SCNSceneRenderer:SCNView是顯示或呈現(xiàn)SceneKit內(nèi)容的視圖弥雹。SCNSceneRenderer是一個協(xié)議垃帅,定義用于視圖的一些重要方法。
SCNScene: 表現(xiàn)一個場景剪勿,是所有SceneKit內(nèi)容的一個容器贸诚。場景可以從使用3D著作工具創(chuàng)建的一個文件中加載,也可以編程創(chuàng)建厕吉,場景需要在一個視圖上顯示酱固。
SCNNode:一個場景的基本構(gòu)造塊,表示scene graph樹的一個節(jié)點头朱。scene graph樹定義了場景上節(jié)點之間的邏輯結(jié)構(gòu)运悲,通過為一個節(jié)點附屬geometries、lights项钮、cameras來提供場景的可視內(nèi)容班眯。
SCNGeometry、SCNLight寄纵、SCNCamera:分別是geometries鳖敷、lights、cameras對應的類程拭。SCNGeometry為場景提供形狀定踱、文本或定制頂點數(shù)據(jù),SCNLight為場景提供陰影效果恃鞋,SCNCamera為場景提供可視點崖媚。
SCNMaterial:為SCNGeometry對象定義表面外觀屬性,規(guī)定對象表面如何著色或紋理以及如何反應燈光恤浪。
SceneKit內(nèi)容的動畫:
SceneKit動畫基于Core Animation 框架畅哑,可以隱式或顯式創(chuàng)建。
隱式創(chuàng)建是實際是通過動畫節(jié)點的一些動畫屬性來實現(xiàn):SceneKit自動在run loop一次運行期間對一個場景包含節(jié)點屬性的所有改變組合成一個原子操作水由,稱為一個事務荠呐,由SCNTransaction 類表示;當設置SCNTransaction類的動畫周期不為0時,所有對節(jié)點動畫屬性的改變自動執(zhí)行動畫泥张。
如下代碼片段所示:
func fallAndFade(sender: a href="" AnyObject /a ) {
SCNTransaction.setAnimationDuration(1.0)
textNode.position = SCNVector3(x: 0.0, y: -10.0, z: 0.0)
textNode.opacity = 0.0
}
顯式創(chuàng)建動畫時呵恢,可以選擇CAAnimation一種類型的子類來創(chuàng)建特定類型的動畫。使用key-value為動畫規(guī)定屬性及設置動畫參數(shù)媚创,然后把創(chuàng)建的動畫附屬到場景的一個或多個元素渗钉。可以使用不同的Core Animation動畫類組合或序列化幾個動畫或創(chuàng)建動畫在幾個 keyframe值之間插入屬性值钞钙。
如下代碼片段為顯式創(chuàng)建動畫的例子:
let animation = CABasicAnimation(keyPath: "geometry.extrusionDepth")
animation.fromValue = 0.0
animation.toValue = 100.0
animation.duration = 1.0
animation.autoreverses = true
animation.repeatCount = Float.infinity
textNode.addAnimation(animation, forKey: “extrude")
SceneKit也支持使用SCNSceneSource 類從一個場景文件中加載CAAnimation動畫對象鳄橘,然后附屬它到SCNNode對象。
5)Metal
Metal框架是一個OpenGL ES類似的底層API芒炼,為GPU加速的先進的3D圖形呈現(xiàn)或數(shù)據(jù)并行計算任務提供支持瘫怜。Metal負責和3D繪圖硬件交互,為圖形和計算命令的組織焕议、處理宝磨、提交和相關(guān)資源和數(shù)據(jù)的管理提供一個細粒度的、底層的支持流式計算的現(xiàn)代API盅安。Metal的目標是在執(zhí)行GPU任務時盡量減少CPU的負載洪灯,消除在GPU執(zhí)行圖形和數(shù)據(jù)并行計算操作時的性能瓶頸嚣伐,能夠有效的使用多線程并行創(chuàng)建和提交命令到GPU览绿。
Metal也提供了一個映射編程語言用來編寫能夠被Metal應用使用的圖形映射或計算函數(shù)只冻。Metal映射語言編寫的代碼能夠在編譯時與應用代碼一起被編譯,然后在運行時被加載到GPU上執(zhí)行蝙寨;也支持運行時對Metal 映射語言代碼進行編輯晒衩。
在Metal架構(gòu)中包括如下幾個重要的類或協(xié)議:
1、MTLDevice協(xié)議和對象
一個MTLDevice代表一個執(zhí)行命令的GPU設備墙歪,MTLDevice協(xié)議為其定義了相關(guān)接口听系,包括查詢設備能力屬性和創(chuàng)建其它設備特定的對象等接口,例如創(chuàng)建命令隊列虹菲、從內(nèi)存中分配緩沖區(qū)以及創(chuàng)建紋理等靠胜。
應用通過調(diào)用MTLCreateSystemDefaultDevice 函數(shù)來獲取一個系統(tǒng)能夠使用的MTLDevice對象。
2毕源、命令和命令編碼器
在Metal框架中浪漠,3D圖形呈現(xiàn)命令、計算命令和blitting命令在提交到特定設備GPU上執(zhí)行前必須進行相應的格式編碼霎褐,以便能夠被GPU識別和執(zhí)行址愿。
Metal框架為每種命令提供了一種編碼器協(xié)議:
MTLRenderCommandEncoder 協(xié)議:提供接口用來編碼一個單次循環(huán)呈現(xiàn)期間要執(zhí)行的3D圖形呈現(xiàn)命令。MTLRenderCommandEncoder 對象用來代表一次圖形呈現(xiàn)流程的呈現(xiàn)狀態(tài)和繪制命令冻璃。
MTLComputeCommandEncoder協(xié)議:提供接口用來編碼數(shù)據(jù)并行計算任務响谓。
MTLBlitCommandEncoder協(xié)議:提供接口用來編碼在緩沖和紋理之間的簡單拷貝操作损合。
在同一時刻,僅能有一個命令編碼器激活來添加命令到一個命令緩沖空間上娘纷,即每一個命令編碼器必須在另一個使用相同命令緩沖空間的命令編碼器創(chuàng)建前結(jié)束塌忽。
Metal為了支持多個不同任務的并行執(zhí)行,提供了一個MTLParallelRenderCommandEncoder協(xié)議來支持多個MTLBlitCommandEncoder在不同線程同時運行提交不同的命令緩沖到同一個命令緩沖空間失驶。每一個線程有一個它自己的命令緩沖對象,在同一時刻枣购,該緩沖對象只能被該線程的一個命令編碼器存取嬉探。
MTLParallelRenderCommandEncoder對象允許一次呈現(xiàn)循環(huán)的命令編碼分解到多個命令編碼器進行編碼,使用多線程進行并行處理來提高處理效率棉圈。
一個命令編碼器對象調(diào)用endEncoding方法來結(jié)束涩堤。
命令編碼器對象的創(chuàng)建:
命令編碼器對象由MTLCommandBuffer對象負責創(chuàng)建。MTLCommandBuffer協(xié)議定義了如下方法用來創(chuàng)建相應類型的命令編碼器對象:
renderCommandEncoderWithDescriptor:為執(zhí)行圖形呈現(xiàn)任務創(chuàng)建一個MTLRenderCommandEncoder 對象分瘾。方法的參數(shù)MTLRenderPassDescriptor表現(xiàn)一個編碼呈現(xiàn)命令的目標(是一個附屬點的集合胎围,最多可以包括四個顏色點數(shù)據(jù)附屬點、一個深度點數(shù)據(jù)附屬點德召、一個圖案點數(shù)據(jù)附屬點)白魂,在MTLRenderPassDescriptor對象的附屬點屬性中指定要呈現(xiàn)的圖形目標。
computeCommandEncoder方法為數(shù)據(jù)并行計算任務創(chuàng)建一個MTLComputeCommandEncoder 對象上岗。
blitCommandEncoder 方法為內(nèi)存Blit操作和紋理填充操及mipmaps的產(chǎn)生等操作創(chuàng)建一個MTLBlitCommandEncoder 對象福荸。
parallelRenderCommandEncoderWithDescriptor: 方法創(chuàng)建一個MTLParallelRenderCommandEncoder對象。呈現(xiàn)目標由 參數(shù)MTLRenderPassDescriptor規(guī)定肴掷。
3敬锐、命令緩沖MTLCommandBuffer對象及協(xié)議
在經(jīng)過命令編碼器編碼后的命令被命令編碼器添加到一個稱為命令緩沖的MTLCommandBuffer對象上,然后該CommandBuffer對象被提交到GPU來執(zhí)行其中包含的命令呆瞻。
MTLCommandBuffer協(xié)議為CommandBuffer對象定義接口以及提供命令編碼器的創(chuàng)建台夺、提交CommandBuffer到一個命令隊列以及檢查狀態(tài)等操作方法。
一個CommandBuffer對象包含打算在特定設備(GPU)上執(zhí)行的被編碼的命令痴脾。一旦所有的編碼完成颤介,CommandBuffer本身必須提交到一個命令隊列,并標記命令緩沖為準備好狀態(tài)明郭,以便能夠被GPU 執(zhí)行买窟。
在標準標準應用中,通常一個呈現(xiàn)幀的呈現(xiàn)命令使用一個線程被編碼進一個命令緩沖中薯定。
MTLCommandBuffer對象的創(chuàng)建和相應方法:
一個MTLCommandBuffer對象由MTLCommandQueue的commandBuffer方法或commandBufferWithUnretainedReferences方法創(chuàng)建始绍。
一個MTLCommandBuffer對象僅能提交到創(chuàng)建它的MTLCommandQueue 對象中。
一個MTLCommandBuffer對象還實現(xiàn)協(xié)議定義的如下方法:
enqueue方法用來在命令隊列中為該命令緩沖保留一個位置话侄。
commit 方法使MTLCommandBuffer對象被提交執(zhí)行亏推。
addScheduledHandler:方法用來為一個命令緩沖對象登記一個在該命令緩沖被調(diào)度時被調(diào)用的代碼執(zhí)行塊学赛。可以為一個命令緩沖對象登記多個調(diào)度執(zhí)行塊吞杭。
waitUntilScheduled 方法等待命令緩沖被調(diào)度及在為該命令緩沖登記的所有調(diào)度執(zhí)行塊已經(jīng)執(zhí)行完盏浇。
addCompletedHandler:方法為一個命令緩沖對象登記一個在設備已經(jīng)執(zhí)行完該命令緩沖后被調(diào)用的代碼執(zhí)行塊。也可以為一個命令緩沖對象登記多個完成執(zhí)行代碼塊芽狗。
waitUntilCompleted 方法等待命令緩沖中命令被設備執(zhí)行完和為該命令緩沖登記的所有完成執(zhí)行塊都執(zhí)行結(jié)束绢掰。
presentDrawable:方法用來在命令緩沖對象被調(diào)度時呈現(xiàn)一個可顯示資源(CAMetalDrawable 對象)的內(nèi)容。
4童擎、MTLCommandQueue協(xié)議和命令隊列對象
MTLCommandQueue協(xié)議為包含命令緩沖的一個隊列滴劲。命令隊列用來組織其中包含的命令緩沖對象的執(zhí)行次序和控制命令隊列中的命令緩沖對象包含的命令什么時候被執(zhí)行。
MTLCommandQueue協(xié)議為命令隊列定義了接口顾复,主要的接口包括命令緩沖對象的創(chuàng)建班挖。
MTLCommandQueue對象的創(chuàng)建:
使用MTLDevice對象的newCommandQueue方法或newCommandQueueWithMaxCommandBufferCount:方法來創(chuàng)建一個命令隊列對象。
下圖為以上這些對象之間的關(guān)系圖:
20141103175424013.jpg
如圖中所示:必須為一個呈現(xiàn)命令編碼器設置呈現(xiàn)相關(guān)的狀態(tài)芯砸、設置和創(chuàng)建相關(guān)的呈現(xiàn)用到的緩沖區(qū)萧芙、紋理等Metal資源對象。
為呈現(xiàn)命令編碼器指定的狀態(tài)包括一個呈現(xiàn)管道流水線狀態(tài)(Render Pipeline State),一個深度和圖案狀態(tài)(Depth Stencil State),一個采樣狀態(tài)(Sampler State)假丧。
一個Blit命令編碼器與一個緩沖區(qū)和一個紋理關(guān)聯(lián)双揪,用來在兩者之間進行Blit操作。
命令編碼器指定圖形或計算功能時可以分配三種類型的MTLResource Metal資源對象使用:
MTLBuffer 表現(xiàn)一個能夠包含任意類型數(shù)據(jù)的無格式內(nèi)存虎谢。MTLBuffer通常用于多邊形頂點vertex盟榴、著色器shader及計算狀態(tài)數(shù)據(jù)。
MTLTexture表現(xiàn)一個有著特定紋理類型和點格式的具有相應格式的圖像數(shù)據(jù)婴噩。紋理對象可以作為多邊形頂點vertex擎场、片段fragment或計算功能的一個源,也可以在呈現(xiàn)描述符中作為圖形呈現(xiàn)的輸出目標几莽。
MTLSamplerState對象當一個圖形或計算功能在一個MTLTexture上執(zhí)行紋理采樣操作時使用迅办,用來定義地址、過濾和其它屬性章蚣。
圖形呈現(xiàn)編碼器MTLRenderCommandEncoder 可以使用setVertex及setFragment 方法組作為其參數(shù)來為相應的映射函數(shù)分配一個或多個資源站欺。
5、CAMetalLayer 對象和CAMetalDrawable 協(xié)議
Core Animation定義了一個CAMetalLayer類和一個CAMetalDrawable 協(xié)議用來提供一個Metal內(nèi)容呈現(xiàn)的層后備視圖纤垂。CAMetalLayer對象包含有關(guān)要呈現(xiàn)內(nèi)容的位置矾策、尺寸、可視屬性(背景顏色峭沦、邊界和陰影)及Metal呈現(xiàn)內(nèi)容使用到的資源等贾虽。CAMetalDrawable 協(xié)議是MTLDrawable 的擴展,指定了可顯示資源對象要符合的MTLTexture協(xié)議吼鱼,使可顯示資源對象可用作呈現(xiàn)命令的目標蓬豁。
為了實現(xiàn)Metal內(nèi)容在一個CAMetalLayer對象的呈現(xiàn)绰咽,應為每次呈現(xiàn)流程創(chuàng)建一個CAMetalDrawable對象,從中得到它包含的MTLTexture 對象地粪,然后在呈現(xiàn)流水線描述MTLRenderPipelineDescriptor 的顏色附屬點屬性中使用取募,指定其為圖形呈現(xiàn)命令的目標。
一個CAMetalLayer對象調(diào)用CAMetalLayer 對象的nextDrawable 方法來創(chuàng)建蟆技。
在創(chuàng)建一個可顯示資源作為圖形命令的目標后玩敏,就可以調(diào)用如下步驟完成圖形的繪制。
1)质礼、首先創(chuàng)建一個MTLCommandQueue 對象聊品,然后使用它創(chuàng)建一個MTLCommandBuffer對象;
2)几苍、創(chuàng)建一個MTLRenderPassDescriptor對象,為其規(guī)定用作圖形緩沖中的編碼呈現(xiàn)命令目標的附屬點集合陈哑;然后使用這個MTLRenderPassDescriptor 對象創(chuàng)建一個MTLRenderCommandEncoder對象妻坝;
3) 創(chuàng)建相應的Metal資源對象,來存儲繪制用到資源數(shù)據(jù)惊窖,如頂點坐標和頂點顏色數(shù)據(jù)刽宪;并調(diào)用MTLRenderCommandEncoder的setVertex:offset:atIndex: 和setFragment :offset:atIndex:方法來為呈現(xiàn)編碼器指定用到的資源;
4) 創(chuàng)建一個MTLRenderPipelineDescriptor 對象并為其指定vertexFunction和fragmentFunction 屬性界酒,這些屬性使用Metal映射語言代碼中讀取的相應映射函數(shù)MTLFunction對象來設置圣拄。
5)使用MTLDevice的newRenderPipelineStateWithDescriptor:error:方法或類似方法并根據(jù)MTLRenderPipelineDescriptor創(chuàng)建一個MTLRenderPipelineState對象;然后調(diào)用MTLRenderCommandEncoder 的setRenderPipelineState: 方法來為呈現(xiàn)編碼器對象MTLRenderCommandEncoder設置管道流水線毁欣;
6)調(diào)用MTLRenderCommandEncoder 的drawPrimitives:vertexStart:vertexCount: 方法來執(zhí)行圖形的呈現(xiàn)庇谆,然后調(diào)用MTLRenderCommandEncoder的endEncoding 方法來結(jié)束本次呈現(xiàn)流程的編碼,最后調(diào)用MTLCommandBuffer 的commit方法來在GPU上執(zhí)行整個繪制命令凭疮。