我开始从事一个项目,旧的大学使用金属来绘制一些图形。我对金属的经验为零,目前我正在寻找一种快速的解决方案,以便在此MTKView中添加标签,稍后我将学习有关金属的更多信息。
这是代码的最新步骤:
for coordinate in coordinates {
let circleVertice = CircleVertex(x: coordinate, y: 200, radius: 20)
rrIntervals += circleVertice.toVertices(perimeterPoints: perimeterPoints)
}
如您所见,我有一个坐标,它是标签的坐标,它随图形一起移动,直到它离开屏幕为止。例如,我想在此处添加带有"Test"
字符串的标签,用此坐标在此MTKView中添加此标签的最佳和最快方法是什么。此代码在MTKView
class
如果可以在这里帮助我,您将挽救我的生命。谢谢
这是我的项目中的金属设置,@ 0xBFE1A8,您可以帮助我在此设置中实现SKRenderer
吗?
protocol MetalSetupDelegate: class {
func prepareEncoder(id: String, encoder: MTLRenderCommandEncoder,
drawable: CAMetalDrawable, bufferDataSource: BufferDatasource) throws
}
class MetalSetup {
struct Functions {
let id: String
let vertex: String
let fragment: String
init(id: String = "default", vertex: String, fragment: String) {
self.id = id
self.vertex = vertex
self.fragment = fragment
}
}
enum Error: Swift.Error {
case unableToInitialize(String)
}
let device: MTLDevice
let library: MTLLibrary
let pixelFormat = MTLPixelFormat.bgra8Unorm
let commandQueue: MTLCommandQueue
private var pipelineStates: [String: MTLRenderPipelineState] = [:]
let bufferDataSource: BufferDatasource
weak var delegate: MetalSetupDelegate?
convenience init(device: MTLDevice, functions: Functions) throws {
try self.init(device: device, functions: [functions])
}
init(device: MTLDevice, functions: [Functions]) throws {
self.device = device
guard let url = Bundle(for: type(of: self)).url(forResource: "default", withExtension: "metallib") else {
throw Error.unableToInitialize(String(describing: URL.self))
}
library = try device.makeLibrary(filepath: url.path)
guard let commandQueue = device.makeCommandQueue() else {
throw Error.unableToInitialize(String(describing: MTLCommandQueue.self))
}
self.commandQueue = commandQueue
bufferDataSource = BufferDatasource(inFlightBuffersCount: 3)
for function in functions {
guard let vertexProgram = library.makeFunction(name: function.vertex) else {
throw Error.unableToInitialize(String(describing: MTLFunction.self))
}
guard let fragmentProgram = library.makeFunction(name: function.fragment) else {
throw Error.unableToInitialize(String(describing: MTLFunction.self))
}
let pipelineStateDescriptor = MTLRenderPipelineDescriptor()
pipelineStateDescriptor.vertexFunction = vertexProgram
pipelineStateDescriptor.fragmentFunction = fragmentProgram
pipelineStateDescriptor.colorAttachments[0].pixelFormat = pixelFormat
let pipelineState = try device.makeRenderPipelineState(descriptor: pipelineStateDescriptor)
pipelineStates[function.id] = pipelineState
}
}
func render(drawable: CAMetalDrawable, renderPassDescriptor: MTLRenderPassDescriptor) throws {
guard let delegate = delegate else {
return
}
guard let commandBuffer = commandQueue.makeCommandBuffer() else {
throw Error.unableToInitialize(String(describing: MTLCommandBuffer.self))
}
renderPassDescriptor.colorAttachments[0].loadAction = .clear
guard let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor) else {
throw Error.unableToInitialize(String(describing: MTLRenderCommandEncoder.self))
}
do {
bufferDataSource.dispatchWait()
commandBuffer.label = "Main Command Buffer"
commandBuffer.addCompletedHandler { [unowned self] _ -> Void in
self.bufferDataSource.dispatchSignal()
}
renderEncoder.label = "Final Pass Encoder"
for (id, pipelineState) in pipelineStates {
renderEncoder.pushDebugGroup("Drawing buffers for id: \(id)")
renderEncoder.setRenderPipelineState(pipelineState)
try delegate.prepareEncoder(id: id, encoder: renderEncoder, drawable: drawable, bufferDataSource: bufferDataSource)
renderEncoder.popDebugGroup()
}
renderEncoder.endEncoding()
commandBuffer.present(drawable)
commandBuffer.commit()
} catch {
renderEncoder.endEncoding()
bufferDataSource.dispatchSignal()
throw error
}
}
}