本系列文章是對 metalkit.org 上面MetalKit內容的全面翻譯和學習.
現在,你可以注意到我很喜歡Swift
.同時我也是個Xcode
playgrounds的狂熱愛好者.本週我們會把我們的Metal
程式碼放到playground中.歡呼吧,為了playgrounds中的Metal
原型!
讓我們從建立一個新的OS X
版Xcode
playground開始.建立好後,單擊Show the Assistant editor
按鈕並按下Command + 1
顯示Project navigator
導航區.你的playground看起來應該這樣:
第一件事就是在Project navigator
中的Resources資料夾下建立Shaders.metal,程式碼和本系列前一章節保持一致.然後,我們在Sources資料夾下建立MathUtils.swift和MetalView.swift.惟一要改動的地方是在MathUtils.swift
中為Vertex
結構體建立一個初始化方法:
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
的.同時,我們再建立第二個初始化方法,這樣我們就可能建立一個指定frame的MetalView
了:
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()!
複製程式碼
提示錯誤資訊:
MTLLibrary.mm:1016: failed assertion `filepath must not be nil.'
複製程式碼
這是因為playground沒有預設的filepath
來給我們使用,我們需要自己建立:
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
,你會看到一個類似的檢視:
原始碼source code 已釋出在Github上.
下次見!