“无法将模块“金属”加载为“金属””

时间:2019-10-23 04:19:46

标签: swift metal xcode11

我正在关注一个教程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是教程说要创建的文件

3 个答案:

答案 0 :(得分:1)

您需要按以下方式导入Metal框架(在创建MTLDevice 下进行提及)

import Metal

当前您正在执行以下操作,这是错误的,

import metal

答案 1 :(得分:1)

编译器检测到与Metal类似的名称,即metal。有时,库会使用不同的版本来更改名称,这就是为什么它可能与您正在关注的教程不同的原因。

尝试按照错误提示进行操作,并将导入替换为:import metal

答案 2 :(得分:0)

您需要一个var vertexBuffer: MTLBuffer变量