[kit] Shuffle things around so delegate doesn't have to be given in init()

Classes that use the Renderer might not be ready to assign themselves as delegate when the Renderer is initialized
This commit is contained in:
Eryn Wells 2017-08-18 09:03:01 -07:00
parent 43caa7d844
commit 6b663f92e8

View file

@ -25,59 +25,75 @@ struct Vertex {
} }
public class Renderer: NSObject, MTKViewDelegate { public class Renderer: NSObject, MTKViewDelegate {
var delegate: RendererDelegate public var delegate: RendererDelegate? = nil {
didSet {
guard let delegate = delegate else {
return
}
let view = delegate.metalView
view.device = device
do {
let library = try device.makeDefaultLibrary(bundle: Bundle.main)
let vertexShader = library.makeFunction(name: "passthroughVertexShader")
let fragmentShader = library.makeFunction(name: "sampleToColorShader")
let pipelineStateDescriptor = MTLRenderPipelineDescriptor()
pipelineStateDescriptor.label = "Render Pipeline"
pipelineStateDescriptor.vertexFunction = vertexShader
pipelineStateDescriptor.fragmentFunction = fragmentShader
if let renderAttachment = pipelineStateDescriptor.colorAttachments[0] {
renderAttachment.pixelFormat = view.colorPixelFormat
// Pulled all this from SO. I don't know what all this does...
// https://stackoverflow.com/q/43727335/1174185
renderAttachment.isBlendingEnabled = true
renderAttachment.alphaBlendOperation = .add
renderAttachment.rgbBlendOperation = .add
renderAttachment.sourceRGBBlendFactor = .sourceAlpha
renderAttachment.sourceAlphaBlendFactor = .sourceAlpha
renderAttachment.destinationRGBBlendFactor = .oneMinusSourceAlpha
renderAttachment.destinationAlphaBlendFactor = .oneMinusSourceAlpha
}
renderPipelineState = try device.makeRenderPipelineState(descriptor: pipelineStateDescriptor)
try delegate.field.setupMetal(withDevice: device)
} catch let e {
fatalError("\(e)")
}
}
}
private var device: MTLDevice private var device: MTLDevice
private var commandQueue: MTLCommandQueue private var commandQueue: MTLCommandQueue
private var renderPipelineState: MTLRenderPipelineState private var renderPipelineState: MTLRenderPipelineState? = nil
public init(delegate: RendererDelegate) throws {
self.delegate = delegate
override public init() {
guard let device = MTLCreateSystemDefaultDevice() else { guard let device = MTLCreateSystemDefaultDevice() else {
throw RendererError.MetalError("Unable to create Metal system device") fatalError("Unable to create Metal system device")
} }
let view = delegate.metalView
self.device = device self.device = device
view.device = device
try delegate.field.setupMetal(withDevice: device)
let library = try device.makeDefaultLibrary(bundle: Bundle.main)
let vertexShader = library.makeFunction(name: "passthroughVertexShader")
let fragmentShader = library.makeFunction(name: "sampleToColorShader")
let pipelineStateDescriptor = MTLRenderPipelineDescriptor()
pipelineStateDescriptor.label = "Render Pipeline"
pipelineStateDescriptor.vertexFunction = vertexShader
pipelineStateDescriptor.fragmentFunction = fragmentShader
if let renderAttachment = pipelineStateDescriptor.colorAttachments[0] {
renderAttachment.pixelFormat = view.colorPixelFormat
// Pulled all this from SO. I don't know what all this does...
// https://stackoverflow.com/q/43727335/1174185
renderAttachment.isBlendingEnabled = true
renderAttachment.alphaBlendOperation = .add
renderAttachment.rgbBlendOperation = .add
renderAttachment.sourceRGBBlendFactor = .sourceAlpha
renderAttachment.sourceAlphaBlendFactor = .sourceAlpha
renderAttachment.destinationRGBBlendFactor = .oneMinusSourceAlpha
renderAttachment.destinationAlphaBlendFactor = .oneMinusSourceAlpha
}
renderPipelineState = try device.makeRenderPipelineState(descriptor: pipelineStateDescriptor)
commandQueue = device.makeCommandQueue() commandQueue = device.makeCommandQueue()
super.init() super.init()
} }
public convenience init(delegate: RendererDelegate) throws {
self.init()
self.delegate = delegate
}
/// MARK: - MTKViewDelegate /// MARK: - MTKViewDelegate
public func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) { public func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {
delegate.renderSize = Size(size: size) delegate?.renderSize = Size(size: size)
} }
public func draw(in view: MTKView) { public func draw(in view: MTKView) {
let field = delegate.field guard let field = delegate?.field else {
return
}
// Two triangles, plus texture coordinates. // Two triangles, plus texture coordinates.
let points: [Vertex] = [ let points: [Vertex] = [
@ -95,7 +111,7 @@ public class Renderer: NSObject, MTKViewDelegate {
let buffer = commandQueue.makeCommandBuffer() let buffer = commandQueue.makeCommandBuffer()
buffer.label = "Render" buffer.label = "Render"
if let renderPass = view.currentRenderPassDescriptor { if let renderPass = view.currentRenderPassDescriptor, let renderPipelineState = renderPipelineState {
let encoder = buffer.makeRenderCommandEncoder(descriptor: renderPass) let encoder = buffer.makeRenderCommandEncoder(descriptor: renderPass)
encoder.label = "Render Pass" encoder.label = "Render Pass"
encoder.setViewport(MTLViewport(originX: 0.0, originY: 0.0, width: Double(view.drawableSize.width), height: Double(view.drawableSize.height), znear: -1.0, zfar: 1.0)) encoder.setViewport(MTLViewport(originX: 0.0, originY: 0.0, width: Double(view.drawableSize.width), height: Double(view.drawableSize.height), znear: -1.0, zfar: 1.0))