Metal入门资料007-MetalKit与Metal区别

写在前面:

对Metal技术感兴趣的同学,可以关注我的专题:Metal专辑
也可以关注我个人的账号:张芳涛
所有的代码存储的Github地址是:Metal

正文

我们来看看使用较新的MetalKit框架与使用较早的Metal框架之间有什么区别。 虽然它们仍然共存,但是MetalKit引入了一些强大的功能,例如:

  • 容易的texture纹理加载(甚至用几行代码进行异步加载)。
  • Model I/O网格和Metal缓冲区之间高效的数据传输。
  • MTKView - 一个方便的Metal-aware视图(后面会有更详细的介绍)。

我将首先提醒你我们在第一章中看到的程序是什么样的:

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()
    }
  }
}

就是这样! 简单和优雅的方式来清除你的背景颜色到你选择的自定义颜色。 现在让我们切换到使用没有MTKViewMetal框架,所以我们需要改为NSView(或iOS中的UIView)的子类。

import Cocoa

class MetalView: NSView {

您会立即注意到一些错误信号,表明以下属性默认不会再提供给我们:

  • a device
  • a drawable
  • a render pass descriptor

我们来解决这个问题。 首先,由于NSView不是Metal-aware,我们需要创建一个CAMetalLayer并告诉NSView使用它作为其背景层。 CAMetalLayer是一个核心动画层,管理用于渲染其内容的纹理池。 要使用Metal进行渲染,我们需要通过从视图的layerClass()类方法中返回它,将此类用作视图的背景层。

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

var metalLayer: CAMetalLayer {
return self.layer as! CAMetalLayer
}

接下来,在render()函数中创建一个新设备并告诉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类,以再次看到为什么这是使用Metal在我们的应用中呈现内容的首选方式:

@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参考文档。

你可能感兴趣的:(Metal入门资料007-MetalKit与Metal区别)