[MetalKit]9-Using-MetalKit-part-8使用MetalKit8

本系列文章是对 metalkit.org 上面MetalKit内容的全面翻译和学习.git

MetalKit系统文章目录github


如今,你能够注意到我很喜欢Swift.同时我也是个Xcodeplaygrounds的狂热爱好者.本周咱们会把咱们的Metal代码放到playground中.欢呼吧,为了playgrounds中的Metal原型!swift

让咱们从建立一个新的OS XXcodeplayground开始.建立好后,单击Show the Assistant editor按钮并按下Command + 1显示Project navigator导航区.你的playground看起来应该这样: bash

chapter08_1.png

第一件事就是在Project navigator中的Resources文件夹下建立Shaders.metal,代码和本系列前一章节保持一致.而后,咱们在Sources文件夹下建立MathUtils.swiftMetalView.swift.唯一要改动的地方是在MathUtils.swift中为Vertex结构体建立一个初始化方法:ide

struct Vertex {
    var position: vector_float4
    var color: vector_float4
    init(pos: vector_float4, col: vector_float4) {
        position = pos
        color = col
    }
}
复制代码

MetalView.swift中咱们须要改的多一些.首先,咱们要让类是public,由于咱们将在Sources文件夹外调用它.所以,初始化方法和drawRect(:) 方法也必须是public的.同时,咱们再建立第二个初始化方法,这样咱们就可能建立一个指定frameMetalView了:post

public class MetalView: MTKView {
    ... 
    required public init(coder: NSCoder) {
        super.init(coder: coder)
    }

    override public init(frame frameRect: CGRect, device: MTLDevice?) {
        super.init(frame: frameRect, device: device)
        createBuffers()
        registerShaders()
    }
    ... 
}
复制代码

下一步,咱们须要作一些奇妙的改动,建立一个Library:学习

let library = device.newDefaultLibrary()!
复制代码

提示错误信息:ui

MTLLibrary.mm:1016: failed assertion `filepath must not be nil.' 复制代码

这是由于playground没有默认的filepath来给咱们使用,咱们须要本身建立:spa

func registerShaders() {
    let path = NSBundle.mainBundle().pathForResource("Shaders", ofType: "metal")
    let input: String?
    let library: MTLLibrary
    let vert_func: MTLFunction
    let frag_func: MTLFunction
    do {
        input = try String(contentsOfFile: path!, encoding: NSUTF8StringEncoding)
        library = try device!.newLibraryWithSource(input!, options: nil)
        vert_func = library.newFunctionWithName("vertex_func")!
        frag_func = library.newFunctionWithName("fragment_func")!
        let rpld = MTLRenderPipelineDescriptor()
        rpld.vertexFunction = vert_func
        rpld.fragmentFunction = frag_func
        rpld.colorAttachments[0].pixelFormat = .BGRA8Unorm
        rps = try device!.newRenderPipelineStateWithDescriptor(rpld)
    } catch let e {
        Swift.print("\(e)")
    }
}
复制代码

注意,咱们告诉playground去找到名为Shaders类型为metal的资源的存放路径.而后,咱们将文件转换为一个长的String并用这些资源建立library.翻译

最后,咱们到playground的主页并建立一个带有frame的MetalView.而后咱们告诉playground展现活跃视图:

import Cocoa
import XCPlayground

let device = MTLCreateSystemDefaultDevice()!
let frame = NSRect(x: 0, y: 0, width: 300, height: 300)
let view = MetalView(frame: frame, device: device)
XCPlaygroundPage.currentPage.liveView = view
复制代码

若是你显示了Assistant editor区的Timeline,你会看到一个相似的视图:

chapter08_2.png

源代码source code 已发布在Github上.

下次见!

相关文章
相关标签/搜索