我很困惑,因为我在Swift 4中创建了一个MTLBuffer但是我无法使用方法didModifyRange。
有趣的是,我仍然可以在Apple文档中找到这个并且没有听说过这个被更改。
为什么错误Value of type 'MTLBuffer' has no member 'didModifyRange'
正在发生?
以下代码会在最新版本的XCode中生成此错误
let device = MTLCreateSystemDefaultDevice()
var buffer = device?.makeBuffer(length: 3, options: [])
let range = Range<Int>(NSRange())
buffer.didModifyRange(range)
答案 0 :(得分:1)
根据documentation,该方法的签名如下:
func didModifyRange(_ range: Range<Int>)
你传递的NSRange
明显不同于Swift Range<Int>
。因此,为了使其工作,只需传递适当的范围对象。
P.S。 Range<Int>
定义了min...max
方案(例如0...100
)。
修改强>
某些Metal
框架签名仅适用于macOS 11.1,包括didModifyRange:
,因此如果您尝试在iOS上调用它,即使标题中包含import Metal
,也会为您提供错误。
所以下面的代码将在macOS 11.1下编译
import Metal
// ...
guard
let device = MTLCreateSystemDefaultDevice(),
let buffer = device.makeBuffer(length: 3, options: [])
else {
return
}
buffer.didModifyRange(Range<Int>(1...10))
......并且不会,在iOS下。
答案 1 :(得分:1)
初始化MTLBuffer buffer
后,您可以使用来获取指向它的类型化指针
let x = buffer.contents().bindMemory(to: Float.self, capacity: 1000)
这将返回与buffer.contents()
相同的地址,但步幅与Float
的大小对齐,即您在那里注册了总共capacity
个浮点数。根据需要更改这些参数。
现在您可以直接通过以下方式更新/访问数据
x[0] = 3.14
x[5] = 1.59
etc.
有关更多详细信息,请参阅Apple的bindMemory文档。
答案 2 :(得分:0)
在iOS上没有didModifyRange()
。仅在macOS上可用。
相反,我最终是这样的:
var myVertices: [MyVertex]
...
myVertices[0].color = float4(x: 1, y: 0, z: 0, w: 1)
...
mltBuffer.contents().copyMemory(
from: myVertices,
byteCount: myVertices.count * MemoryLayout<MyVertex>.stride
)