【Metal】使用Metal繪制視圖的內(nèi)容(II)

創(chuàng)建MetalKit視圖和渲染過程以繪制視圖的內(nèi)容

下載

概觀

在本示例中防嗡,您將學(xué)習(xí)使用Metal渲染圖形內(nèi)容的基礎(chǔ)知識宪巨。您將使用MetalKit框架創(chuàng)建一個使用Metal繪制視圖內(nèi)容的視圖。然后,您將編碼用于將修改視圖背景顏色的渲染過程的命名舒裤。

注意
MetalKit自動化窗口任務(wù)系統(tǒng)忍些,加載紋理和處理3D模型數(shù)據(jù)。有關(guān)更多信息,請參閱MetalKit岖沛。

準備MetalKit視圖繪制

MetalKit提供一個名為MTKView的類暑始,他是NSView(macOS中)或者UIView(iOS和tvOS中)的子類。MetalKit處理許多與將您使用Metal繪制內(nèi)容放到屏幕上相關(guān)的細節(jié)婴削。

一個MTKView需要一個Metaldevice對象的引用廊镜,以便在其內(nèi)部創(chuàng)建資源,所以你的第一步是以現(xiàn)有的MTLDevice設(shè)置視圖的device屬性唉俗。

mtkView?.device = MTLCreateSystemDefaultDevice()

MTKView允許您控制其他屬性的行為嗤朴。要將視圖的內(nèi)容改為純色背景,請設(shè)置其clearColor屬性虫溜。您可以使用MTLClearColorMake(_: _: _: _:)函數(shù)創(chuàng)建color雹姊,指定rgba

mtkView?.clearColor = MTLClearColorMake(0.0, 0.5, 1.0, 1.0)

因為您不需要在此示例中繪制動畫內(nèi)容衡楞,所以請配置視圖吱雏,使其僅在需要更新內(nèi)容時繪制,例如視圖改變形狀時:

mtkView?.enableSetNeedsDisplay = true

代理繪圖責(zé)任

MTKView依賴于您的應(yīng)用程序向Metal發(fā)出命令以生成可視內(nèi)容瘾境。MTKView使用代理模式通知您的應(yīng)用程序何時可以繪制歧杏。要接收代理回調(diào),請將視圖的delegate設(shè)置為符合MTKViewDelegate協(xié)議的對象迷守。

mtkView?.delegate = renderer

代理實現(xiàn)的兩種方法:

  • 只要內(nèi)容的大小發(fā)生變化犬绒,視圖就會調(diào)用mtkView(_:drawableSizeWillChange:)方法。當包含視圖的窗口調(diào)整大小或設(shè)備方向更改時(在iOS上)兑凿,會發(fā)生這種情況凯力。這允許您的應(yīng)用根據(jù)根據(jù)其呈現(xiàn)的分辨率調(diào)整視圖大小。
  • 只要有時間更新視圖內(nèi)容急膀,試圖就會調(diào)用draw(in:)方法沮协。在此方法中,您將創(chuàng)建一個命令緩沖區(qū)卓嫂,編碼命令慷暂,告訴GPU繪制什么及何時在屏幕上顯示它,并將該命令緩沖區(qū)排入隊列以供GPU執(zhí)行晨雳。這有時被稱為繪制框架行瑞。您可以將框架視為生成在屏幕上顯示的單個圖像的所有工作。在交互式應(yīng)用程序中餐禁,如游戲血久,您可以每秒繪制許多幀。

在此示例中帮非,調(diào)用類APPLRenderer實現(xiàn)代理方法并承擔(dān)繪制責(zé)任氧吐。視圖控制器視圖控制器創(chuàng)建此類的實例并將其設(shè)置為視圖的代理讹蘑。

創(chuàng)建渲染通道描述符(Render Pass Descriptor)

繪制時,GPU會將結(jié)果存儲到紋理中筑舅,紋理是包含圖像數(shù)據(jù)并可供GPU訪問的內(nèi)存塊座慰。在此示例中,將MTKView創(chuàng)建繪制到視圖中所需的所有紋理翠拣。他創(chuàng)建多個紋理版仔,以便在渲染到另一個紋理的過程中可以顯示一個紋理的內(nèi)容。

要繪制误墓,您需要創(chuàng)建一個渲染過程蛮粮,它是一系列渲染命令,可以繪制成一組紋理谜慌。在渲染過程中使用時然想,紋理也稱為渲染目標。要創(chuàng)建渲染過程欣范,需要一個渲染過程描述符又沾,一個MTLRenderPassDescriptor實例。在此示例中熙卡,不要配置自己的渲染過程描述符,而是要求MetalKit視圖為您創(chuàng)建一個励饵。

guard let renderPassDescriptor = view.currentRenderPassDescriptor else { return }

渲染過程描述符渲染目標集驳癌,以及如何在渲染過程的開始和結(jié)束時處理它們。渲染過程還定義了渲染的其他一些方面役听,這些方面不屬于此示例的一部分颓鲜。視圖返回一個渲染過程描述符,其中包含指向視圖紋理之一的單一顏色附件典予,否則根據(jù)視圖的屬性配置渲染過程甜滨。默認情況下,這意味著渲染過程開始瘤袖,渲染目標將被刪除為與視圖clearColor屬性匹配的純色衣摩,并且在渲染過程結(jié)束時,所有更改都將存儲會紋理捂敌。

因為視圖渲染過程描述符可能nil艾扮,所以您應(yīng)該測試以確保在創(chuàng)建渲染過程之前渲染過程描述符(Render Pass Descriptor)對象是non-nil

創(chuàng)建渲染通道

您可以使用MTLRenderCommand對象將其編碼帶命令緩沖區(qū)中來創(chuàng)建渲染過程占婉。調(diào)用命令緩沖區(qū)的makeRenderCommandEncoder(descriptor:)方法并傳入渲染過程描述符泡嘴。

let commandEncoder = commandBuffer?.makeRenderCommandEncoder(descriptor: renderPassDescriptor)

在此示例中,您不對繪圖命令進行任何編碼逆济,因此渲染過程唯一要做的就是擦除紋理酌予。調(diào)用編碼器的endEncoding方法以指示傳遞完成磺箕。

commandEncoder?.endEncoding()

向屏幕呈現(xiàn)可繪制對象(Drawable)

繪制到紋理不會自動在屏幕呈現(xiàn)新內(nèi)容。實際上抛虫,屏幕上只能顯示一些紋理松靡。在Metal中,可以在屏幕上顯示的紋理由可繪制對象管理莱褒,要顯示內(nèi)容击困,您將呈現(xiàn)可繪制對象(drawable)

MTKView會自動創(chuàng)建可繪制對象(drawable)來管理紋理广凸,讀取currentDrawable屬性以獲取擁有作為渲染目標的紋理的可繪制對象阅茶。這個視圖返回一個CAMetalDrawable對象,這個對象用來連接到Core Animation谅海。

guard let drawable = view.currentDrawable else { return }

在命令緩沖區(qū)上調(diào)用present(_:)方法脸哀,傳入drawable

commandBuffer?.present(drawable)

此方法告訴Metal扭吁,當命令緩沖區(qū)被安排執(zhí)行時撞蜂,Metal應(yīng)與Core Animation協(xié)調(diào)以在渲染完成后顯示紋理。當Core Animation呈現(xiàn)紋理時侥袜,它將成為視圖的新內(nèi)容蝌诡。在此示例中,這意味著已擦除的紋理將成為視圖的新背景枫吧。此更改與Core Animation為屏幕用戶界面元素進行的其他可視更新一起發(fā)生浦旱。

提交命令緩沖區(qū)

現(xiàn)在您已經(jīng)為該幀發(fā)出了所有命令,請?zhí)峤幻罹彌_區(qū)九杂。

commandBuffer?.present(drawable)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蘸吓,一起剝皮案震驚了整個濱河市维哈,隨后出現(xiàn)的幾起案子夺溢,更是在濱河造成了極大的恐慌邮绿,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件镀层,死亡現(xiàn)場離奇詭異镰禾,居然都是意外死亡,警方通過查閱死者的電腦和手機唱逢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門羡微,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人惶我,你說我怎么就攤上這事妈倔。” “怎么了绸贡?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵盯蝴,是天一觀的道長毅哗。 經(jīng)常有香客問我,道長捧挺,這世上最難降的妖魔是什么虑绵? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮闽烙,結(jié)果婚禮上翅睛,老公的妹妹穿的比我還像新娘。我一直安慰自己黑竞,他們只是感情好捕发,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著很魂,像睡著了一般扎酷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上遏匆,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天法挨,我揣著相機與錄音,去河邊找鬼幅聘。 笑死凡纳,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的帝蒿。 我是一名探鬼主播惫企,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼陵叽!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起丛版,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤巩掺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后页畦,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體胖替,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年豫缨,在試婚紗的時候發(fā)現(xiàn)自己被綠了独令。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡好芭,死狀恐怖燃箭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情舍败,我是刑警寧澤招狸,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布敬拓,位于F島的核電站,受9級特大地震影響裙戏,放射性物質(zhì)發(fā)生泄漏乘凸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一累榜、第九天 我趴在偏房一處隱蔽的房頂上張望营勤。 院中可真熱鬧,春花似錦壹罚、人聲如沸葛作。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽进鸠。三九已至,卻和暖如春形病,著一層夾襖步出監(jiān)牢的瞬間客年,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工漠吻, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留量瓜,地道東北人。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓途乃,卻偏偏與公主長得像绍傲,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子耍共,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354