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

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

下載

概觀

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

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

準(zhǔn)備MetalKit視圖繪制

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

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

mtkView?.device = MTLCreateSystemDefaultDevice()

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

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

因?yàn)槟恍枰诖耸纠欣L制動(dòng)畫內(nèi)容,所以請(qǐng)配置視圖,使其僅在需要更新內(nèi)容時(shí)繪制,例如視圖改變形狀時(shí):

mtkView?.enableSetNeedsDisplay = true

代理繪圖責(zé)任

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

mtkView?.delegate = renderer

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

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

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

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

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

要繪制,您需要?jiǎng)?chuàng)建一個(gè)渲染過(guò)程,它是一系列渲染命令,可以繪制成一組紋理。在渲染過(guò)程中使用時(shí),紋理也稱為渲染目標(biāo)。要?jiǎng)?chuàng)建渲染過(guò)程,需要一個(gè)渲染過(guò)程描述符,一個(gè)MTLRenderPassDescriptor實(shí)例。在此示例中,不要配置自己的渲染過(guò)程描述符,而是要求MetalKit視圖為您創(chuàng)建一個(gè)。

guard let renderPassDescriptor = view.currentRenderPassDescriptor else { return }

渲染過(guò)程描述符渲染目標(biāo)集,以及如何在渲染過(guò)程的開始和結(jié)束時(shí)處理它們。渲染過(guò)程還定義了渲染的其他一些方面,這些方面不屬于此示例的一部分。視圖返回一個(gè)渲染過(guò)程描述符,其中包含指向視圖紋理之一的單一顏色附件,否則根據(jù)視圖的屬性配置渲染過(guò)程。默認(rèn)情況下,這意味著渲染過(guò)程開始,渲染目標(biāo)將被刪除為與視圖clearColor屬性匹配的純色,并且在渲染過(guò)程結(jié)束時(shí),所有更改都將存儲(chǔ)會(huì)紋理。

因?yàn)橐晥D渲染過(guò)程描述符可能nil,所以您應(yīng)該測(cè)試以確保在創(chuàng)建渲染過(guò)程之前渲染過(guò)程描述符(Render Pass Descriptor)對(duì)象是non-nil。

創(chuàng)建渲染通道

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

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

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

commandEncoder?.endEncoding()

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

繪制到紋理不會(huì)自動(dòng)在屏幕呈現(xiàn)新內(nèi)容。實(shí)際上,屏幕上只能顯示一些紋理。在Metal中,可以在屏幕上顯示的紋理由可繪制對(duì)象管理,要顯示內(nèi)容,您將呈現(xiàn)可繪制對(duì)象(drawable)

MTKView會(huì)自動(dòng)創(chuàng)建可繪制對(duì)象(drawable)來(lái)管理紋理,讀取currentDrawable屬性以獲取擁有作為渲染目標(biāo)的紋理的可繪制對(duì)象。這個(gè)視圖返回一個(gè)CAMetalDrawable對(duì)象,這個(gè)對(duì)象用來(lái)連接到Core Animation。

guard let drawable = view.currentDrawable else { return }

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

commandBuffer?.present(drawable)

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

提交命令緩沖區(qū)

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

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

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