我正在使用 Apple 的新 Metal 框架编写 iOS 应用程序。我有一个 Matrix4 对象数组(请参阅Ray Wenderlich 的教程 http://www.raywenderlich.com/81399/ios-8-metal-tutorial-swift-moving-to-3d)我需要通过 MTLDevice.newBufferWithLength() 方法传递给着色器。 Matrix4 对象利用 Apple 的 GLKit(它包含 GLKMatrix4 对象)。
我正在利用 GPU 调用进行实例化。
稍后我会将其更改为一个结构,其中每个实例包含更多数据(不仅仅是 Matrix4 对象)。
如何有效地将 [Matrix4] 对象数组复制到此缓冲区中?
有一个更好的方法吗?同样,我将在将来扩展它以使用包含更多数据的结构。
下面是我的代码的一个子集:
let sizeofMatrix4 = sizeof(Float) * Matrix4.numberofElements()
// This returns an array of [Matrix4] objects.
let boxArray = createBoxArray(parentModelViewMatrix)
let sizeOfUniformBuffer = boxArray.count * sizeOfMatrix4
var uniformBuffer = device.newBufferWithLength(sizeofUniformBuffer, options: .CPUCacheModeDefaultCache)
let bufferPointer = uniformBuffer?.contents()
// Ouch - way too slow. How can I optimize?
for i in 0..<boxArray.count
{
memcpy(bufferPointer! + (i * sizeOfMatrix4), boxArray[i].raw(), sizeOfMatrix4)
}
renderEncoder.setVertexBuffer(uniformBuffer, offset: 0, atIndex: 2)
笔记:
boxArray[i].raw() 方法在 Objective-C 代码中定义如下:
- (void *)raw {
return glkMatrix.m;
}
您可以看到我循环遍历每个数组对象,然后执行 memcpy。我这样做是因为我在将数组视为一组连续的内存时遇到问题。
Thanks!
Swift 数组被承诺是连续的内存,但您需要确保它确实是一个 Swift 数组,而不是秘密的 NSArray。如果您想完全确定,请使用 ContigiousArray。即使其中的对象可以桥接到 ObjC,这也将确保连续的内存。如果您想更多地控制内存,请查看ManagedBuffer
.
这样,您应该使用newBufferWithBytesNoCopy(length:options:deallocator)
在现有内存周围创建 MTL 缓冲区。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)