[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:
parent
43caa7d844
commit
6b663f92e8
1 changed files with 52 additions and 36 deletions
|
@ -25,59 +25,75 @@ struct Vertex {
|
|||
}
|
||||
|
||||
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 commandQueue: MTLCommandQueue
|
||||
private var renderPipelineState: MTLRenderPipelineState
|
||||
|
||||
public init(delegate: RendererDelegate) throws {
|
||||
self.delegate = delegate
|
||||
private var renderPipelineState: MTLRenderPipelineState? = nil
|
||||
|
||||
override public init() {
|
||||
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
|
||||
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()
|
||||
|
||||
super.init()
|
||||
}
|
||||
|
||||
public convenience init(delegate: RendererDelegate) throws {
|
||||
self.init()
|
||||
self.delegate = delegate
|
||||
}
|
||||
|
||||
/// MARK: - MTKViewDelegate
|
||||
|
||||
public func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {
|
||||
delegate.renderSize = Size(size: size)
|
||||
delegate?.renderSize = Size(size: size)
|
||||
}
|
||||
|
||||
public func draw(in view: MTKView) {
|
||||
let field = delegate.field
|
||||
guard let field = delegate?.field else {
|
||||
return
|
||||
}
|
||||
|
||||
// Two triangles, plus texture coordinates.
|
||||
let points: [Vertex] = [
|
||||
|
@ -95,7 +111,7 @@ public class Renderer: NSObject, MTKViewDelegate {
|
|||
let buffer = commandQueue.makeCommandBuffer()
|
||||
buffer.label = "Render"
|
||||
|
||||
if let renderPass = view.currentRenderPassDescriptor {
|
||||
if let renderPass = view.currentRenderPassDescriptor, let renderPipelineState = renderPipelineState {
|
||||
let encoder = buffer.makeRenderCommandEncoder(descriptor: renderPass)
|
||||
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))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue