[MetalKit]2-Using-MetalKit-part-1使用MetalKit1

本系列文章是對 metalkit.org 上面MetalKit內容的全面翻譯和學習.git

MetalKit系統文章目錄程序員


MetalKit 框架是在 WWDC 2015 上發佈的,它給原Metal框架帶來了大量改進和新特性.認識 MTKView, NSView/UIView的一個子類. 它內置了一個Metal layer層,也同時管理着幀緩衝器framebuffer及其渲染目標附件render target attachments,還管理着繪製循環draw loop.github

讓咱們建立一個Cocoa Application(由於iOS模擬器不支持Metal).確保只有SwiftUse Strotyboards區域是選中狀態.接下來,建立一個新的類,名爲MetalView.swift繼承於NSView(暫時).而後,到storyboard中選中View Controller下面的View,設置Identity Inspector中的類爲MetalView類型,以下圖. swift

chapter02-1.png

View Controller也是一樣操做,刪除Identity InspectorClass下面的View Controller,由於咱們用不到它.刪除ViewController.swift由於我也不須要它了.如今回到MetalView.swift文件中,輸入import MetalKit.有兩種方法可讓咱們的類支持繪製:遵照MTKViewDelegate協議並實現它的drawInView(:)方法,或者繼承MTKView並重寫它的drawRect(:)方法.這裏咱們選擇後者,因此將類的類型從NSView改成MTKView,並建立一個新方法名爲render(),內容以下:app

func render() {
    let device = MTLCreateSystemDefaultDevice()!
    self.device = device
    let rpd = MTLRenderPassDescriptor()
    let bleen = MTLClearColor(red: 0, green: 0.5, blue: 0.5, alpha: 1)
    rpd.colorAttachments[0].texture = currentDrawable!.texture
    rpd.colorAttachments[0].clearColor = bleen
    rpd.colorAttachments[0].loadAction = .Clear
    let commandQueue = device.newCommandQueue()
    let commandBuffer = commandQueue.commandBuffer()
    let encoder = commandBuffer.renderCommandEncoderWithDescriptor(rpd)
    encoder.endEncoding()
    commandBuffer.presentDrawable(currentDrawable!)
    commandBuffer.commit()
}
複製代碼

讓咱們一行一行來細看這些代碼.首先,咱們建立一個device.咱們將其設置爲咱們view的屬性device,不然該屬性爲nil程序會崩潰.做爲一個可選項,咱們能夠在繪製以前修改view的drawable屬性.接着,建立一個render pass descriptor(渲染通道描述符) 以便咱們配置渲染通道爲current drawable’s texture附着上初始顏色.爲了有趣一點,咱們建立一個很棒的顏色,由一半藍色一半綠色組成,叫bleen.最後,咱們使用命令緩衝器來建立render command encoder來執行繪製命令.對於每一個繪製循環,當currentRenderPassDescriptor查詢時,建立一個新的MTLRenderPassDescriptor對象.這個對象是基於currentDrawable對象建立的.畫面顯示並非MTKView處理的,因此咱們必須本身先檢查currentRenderPassDescriptorcurrentDrawable都爲爲nil,而後再調用presentDrawable(:)方法.框架

讓咱們參考一下Metal 文檔中的細節.Metal框架包含若干對象:ide

  • device設備-對GPU的抽象,處理命令隊列中的渲染和計算命令
  • command queue命令隊列-一個命令緩衝器的串行隊列,確保儲存的命令按順序執行
  • command buffer命令緩衝器-儲存從命令編碼器中編譯出的指令.當能問執行完全部命令後Metal會通知應用程序.
  • command encoder命令編碼器-將API命令編譯成GPU硬件命令-共有三種類型的編碼器:render(供圖形渲染),compute(供數據並行處理)及blit(供資源複製操做).目前咱們只需關注render command encoder渲染命令編碼器
  • states狀態-例如混合和深度
  • shaders着色器-源碼
  • resources資源-紋理和數據緩衝器

咱們在本系列的下一節中將討論最後3個對象.當前咱們只關注device,queue,bufferencoder.Render Command Encoder (RCE)渲染命令編碼器爲每個單獨的渲染通道提供硬件命令,這意味着全部的渲染都被送入一個單一的framebuffer幀緩衝器對象中(目標集合中).若是另外一個幀緩衝器須要被渲染,會建立一個新的RCE.RCE會爲從graphics popeline圖形管線中給出的vertex頂點fragment片斷肯定狀態,而且插入resources,state changesdraw calls.利用RCE的一個優勢是無需繪製時編譯;應用能夠決定編譯和狀態檢查什麼時候發生,這樣爲程序員提供了很大的性能優點.oop

讓咱們再回到咱們的代碼.在drawRect(:) 方法中調用render()方法:post

override func drawRect(dirtyRect: NSRect) {
    super.drawRect(dirtyRect)
    render()
}
複製代碼

若是你運行應用,你將會看到一個漂亮的,純粹的bleen-ish屏幕: 性能

chapter02-2.png

在下一節中,咱們終於開始介紹shaders,加載textures及管理model data模型數據.代碼 source code 發佈於Github上.

下次見!

相關文章
相關標籤/搜索