我正在关注一个教程https://www.raywenderlich.com/7475-metal-tutorial-getting-started-学习如何使用金属。我已经完全按照本教程的说明做了,在尝试构建它之前没有错误弹出,然后它说构建失败,并出现错误-无法将模块“ metal”加载为“ Metal”。 我在其他任何地方都找不到答案,所以有人可以帮我解决这个问题吗?我是编码的新手,我希望它有一个简单的解决方案。
编辑:因此,我发现确实存在一个非常简单的解决方案。我没有下载本教程的资料。但是,既然有了,又出现了另一个错误,说Use of unresolved identifier 'vertexBuffer'
这是我的完整代码,只是为了解决任何混乱-
viewControllerer.swift-
import Metal
var device: MTLDevice!
var metalLayer: CAMetalLayer!
var pipelineState: MTLRenderPipelineState!
var commandQueue: MTLCommandQueue!
var timer: CADisplayLink!
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
metalLayer = CAMetalLayer() // 1
metalLayer.device = device // 2
metalLayer.pixelFormat = .bgra8Unorm // 3
metalLayer.framebufferOnly = true // 4
metalLayer.frame = view.layer.frame // 5
view.layer.addSublayer(metalLayer) // 6
let dataSize = vertexData.count * MemoryLayout.size(ofValue: vertexData[0]) // 1
vertexBuffer = device.makeBuffer(bytes: vertexData, length: dataSize, options: []) // 2
// 1
let defaultLibrary = device.makeDefaultLibrary()!
let fragmentProgram = defaultLibrary.makeFunction(name: "basic_fragment")
let vertexProgram = defaultLibrary.makeFunction(name: "basic_vertex")
// 2
let pipelineStateDescriptor = MTLRenderPipelineDescriptor()
pipelineStateDescriptor.vertexFunction = vertexProgram
pipelineStateDescriptor.fragmentFunction = fragmentProgram
pipelineStateDescriptor.colorAttachments[0].pixelFormat = .bgra8Unorm
// 3
pipelineState = try! device.makeRenderPipelineState(descriptor: pipelineStateDescriptor)
device = MTLCreateSystemDefaultDevice()
commandQueue = device.makeCommandQueue()
timer = CADisplayLink(target: self, selector: #selector(gameloop))
timer.add(to: RunLoop.main, forMode: .default)
}
let vertexData: [Float] = [
0.0, 1.0, 0.0,
-1.0, -1.0, 0.0,
1.0, -1.0, 0.0
]
func render() {
guard let drawable = metalLayer?.nextDrawable() else { return }
let renderPassDescriptor = MTLRenderPassDescriptor()
renderPassDescriptor.colorAttachments[0].texture = drawable.texture
renderPassDescriptor.colorAttachments[0].loadAction = .clear
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColor(
red: 0.0,
green: 104.0/255.0,
blue: 55.0/255.0,
alpha: 1.0)
let commandBuffer = commandQueue.makeCommandBuffer()!
let renderEncoder = commandBuffer
.makeRenderCommandEncoder(descriptor: renderPassDescriptor)!
renderEncoder.setRenderPipelineState(pipelineState)
renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, index: 0)
renderEncoder
.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: 3, instanceCount: 1)
renderEncoder.endEncoding()
commandBuffer.present(drawable)
commandBuffer.commit()
}
@objc func gameloop() {
autoreleasepool {
self.render()
}
}
}
Shaders.metal
#include <metal_stdlib>
using namespace metal;
vertex float4 basic_vertex( // 1
const device packed_float3* vertex_array [[ buffer(0) ]], // 2
unsigned int vid [[ vertex_id ]]) { // 3
return float4(vertex_array[vid], 1.0); // 4
}
fragment half4 basic_fragment() { // 1
return half4(1.0); // 2
}
注意- Shaders.metal是教程说要创建的文件
答案 0 :(得分:1)
您需要按以下方式导入Metal
框架(在创建MTLDevice 下进行提及)
import Metal
当前您正在执行以下操作,这是错误的,
import metal
答案 1 :(得分:1)
编译器检测到与Metal
类似的名称,即metal
。有时,库会使用不同的版本来更改名称,这就是为什么它可能与您正在关注的教程不同的原因。
尝试按照错误提示进行操作,并将导入替换为:import metal
答案 2 :(得分:0)
您需要一个var vertexBuffer: MTLBuffer
变量