[MetalKit]7-Using-MetalKit-part-6使用MetalKit6

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

MetalKit系統文章目錄ios


讓咱們來看看新的MetalKit框架和之前的Metal框架有什麼不一樣.它們是同時共存的,可是,MetalKit引入了一些強勁的新特性,好比:git

  • 紋理更容易加載(只需幾行代碼就能夠異步加載).
  • Model I/O網格mash和Metal緩衝器buffer之間的高效數據傳輸.
  • MTKView-一個方便的Metal-aware Metal認識的視圖(咱們稍後會深刻研究它).

我將從回顧第一篇中的程序開始:github

import MetalKit

class MetalView: MTKView {

    override func drawRect(dirtyRect: NSRect) {
        super.drawRect(dirtyRect)
        render()
    }
 
    func render() {
        device = MTLCreateSystemDefaultDevice()
        if let rpd = currentRenderPassDescriptor, drawable = currentDrawable {
            rpd.colorAttachments[0].clearColor = MTLClearColorMake(0, 0.5, 0.5, 1.0)
            let command_buffer = device!.newCommandQueue().commandBuffer()
            let command_encoder = command_buffer.renderCommandEncoderWithDescriptor(rpd)
            command_encoder.endEncoding()
            command_buffer.presentDrawable(drawable)
            command_buffer.commit()
        }
    }
}
複製代碼

就是這樣!簡單優雅清理設備的背景色.如今咱們切換到Metal框架,它並無MTKView,因此咱們必須繼承於NSView(iOS上是UIView).swift

import Cocoa

class MetalView: NSView {
複製代碼

你會直接注意到一些錯誤提示,顯示下面的屬性默認狀況下沒有提供給咱們:app

  • a device設備
  • a drawable繪製資源
  • a render pass descriptor渲染通道描述符

讓咱們修復這些錯誤.首先,由於NSView不是Metal-aware Metal認識的,咱們須要建立一個CAMetalLayer並告訴NSView將其用作本身的支持層.CAMetalLayerCore Animation層,它管理着一個用來渲染內容的紋理池.爲了使用Metal來渲染,咱們須要用這個類做爲咱們視圖的支持層,經過在視圖的layerClass() 類方法中返回圖層來實現:框架

override class func layerClass() -> AnyClass {
    return CAMetalLayer.self
}

var metalLayer: CAMetalLayer {
    return self.layer as! CAMetalLayer
}
複製代碼

接下來,在render() 函數中建立一個新的device並告訴metalLayer去引用它,還要設置層使用的像素格式.而後,建立一個drawable.注意,咱們並無使用MTKView提供的currentDrawable.而是,CAMetalLayer提供了一個nextDrawable給咱們使用.最後,建立一個渲染通道描述符.仍是須要注意,咱們沒有提供currentRenderPassDescriptor:異步

let device = MTLCreateSystemDefaultDevice()!
metalLayer.device = device
metalLayer.pixelFormat = .BGRA8Unorm
let drawable = metalLayer.nextDrawable()
let texture = drawable!.texture
let rpd = MTLRenderPassDescriptor()
複製代碼

在結束本章節以前,讓咱們看一下MTKView類,去看看爲何這是在咱們的app中用Metal渲染內容的最佳方式:ide

@available(OSX 10.11, *)
public class MTKView : NSView, NSCoding {
    public init(frame frameRect: CGRect, device: MTLDevice?)
    public init(coder: NSCoder)
    weak public var delegate: MTKViewDelegate?
    public var device: MTLDevice?
    public var currentDrawable: CAMetalDrawable? { get }
    public var framebufferOnly: Bool
    public var presentsWithTransaction: Bool
    public var colorPixelFormat: MTLPixelFormat
    public var depthStencilPixelFormat: MTLPixelFormat
    public var sampleCount: Int
    public var clearColor: MTLClearColor
    public var clearDepth: Double
    public var clearStencil: UInt32
    public var depthStencilTexture: MTLTexture? { get }
    public var multisampleColorTexture: MTLTexture? { get }
    public func releaseDrawables()
    public var currentRenderPassDescriptor: MTLRenderPassDescriptor? { get }
    public var preferredFramesPerSecond: Int
    public var enableSetNeedsDisplay: Bool
    public var autoResizeDrawable: Bool
    public var drawableSize: CGSize
    public var paused: Bool
    public func draw()
}

@available(OSX 10.11, *)
public protocol MTKViewDelegate : NSObjectProtocol {
    public func mtkView(view: MTKView, drawableSizeWillChange size: CGSize)
    public func drawInMTKView(view: MTKView)
}
複製代碼

在這一大堆屬性中,注意咱們感興趣的幾個:device, currentDrawablecurrentRenderPassDescriptor. 另外一個值得注意的地方,是這個類提供了一個協議,MTKViewDelegate屬性.想要了解更多關於這些屬性和函數的知識,要去看MTKView的參考文檔.函數

源代碼source code 已發佈在Github上.

下次見!

相關文章
相關標籤/搜索