如何从 MDLMeshBufferData 中提取数据以填充 MTKMeshBuffer?
How do I pull the data out of a MDLMeshBufferData to fill a MTKMeshBuffer?
我需要从 MDLMeshBufferData 实例创建一个 MTKMeshBuffer 实例。这是一个代码片段:
let mdlm = MDLMesh(scnGeometry:sceneGeometry, bufferAllocator:nil)
let mdlSubmesh:MDLSubmesh = mdlm.submeshes?[ 0 ] as! MDLSubmesh
let mdlIndexBufferData:MDLMeshBufferData = mdlSubmesh.indexBuffer as! MDLMeshBufferData
let d:Data = mdlIndexBufferData.data
let mtlIndexBuffer:MTKMeshBuffer = device.makeBuffer(bytes: ???, length: ???, options:MTLResourceOptions.storageModeShared) as! MTKMeshBuffer
那个???是我需要填补的位。有人可以告诉我正确的 API 用于从 MDL 缓冲区中提取位以填充 MTK 缓冲区吗?
通过尝试从网格中提取数据并将其填充到 Metal 缓冲区中,您实际上是在为自己做更多的工作 "manually"。此外,MTKMeshBuffer
不是 MTLBuffer
— 它 包含 金属缓冲区,以及使用该缓冲区进行渲染时可能需要的信息.
你实际上要做的是让模型 I/O 为你分配 MetalKit 缓冲区 而不是你自己做,这意味着 MetalKit 为数据分配 Metal 缓冲区所以你不必复制它。然后使用 MetalKit 访问网格和缓冲区。像这样的东西(未经测试):
let allocator = MTKMeshBufferAllocator(device: myMetalDevice)
let mdlMesh = MDLMesh(scnGeometry: sceneGeometry, bufferAllocator: allocator)
let mtkMesh = try! MTKMesh(mesh: mdlMesh, device: myMetalDevice)
// ~~~~ <- in real code, please handle errors
// then, at render time...
for (index, vertexBuffer) in mtkMesh.vertexBuffers.enumerated() {
// vertexBuffer is a MTKMeshBuffer, containing an MTLBuffer
renderEncoder.setVertexBuffer(vertexBuffer.buffer,
offset: vertexBuffer.offset,
at: index)
}
for submesh in mtkMesh.submeshes {
// submesh is a MTKSubmesh, containing an MTKMeshBuffer
renderEncoder.drawIndexedPrimitives(type: submesh.primitiveType,
indexCount: submesh.indexCount,
indexType: submesh.indexType,
indexBuffer: submesh.indexBuffer.buffer,
indexBufferOffset: submesh.indexBuffer.offset)
}
解决方案是为每个顶点缓冲区和索引缓冲区构建 MTLBuffers,并在绘制循环中使用它们。工作正常。
参见:
https://github.com/turner/HelloMetal 和 运行 Hello SceneKit 目标。
我需要从 MDLMeshBufferData 实例创建一个 MTKMeshBuffer 实例。这是一个代码片段:
let mdlm = MDLMesh(scnGeometry:sceneGeometry, bufferAllocator:nil)
let mdlSubmesh:MDLSubmesh = mdlm.submeshes?[ 0 ] as! MDLSubmesh
let mdlIndexBufferData:MDLMeshBufferData = mdlSubmesh.indexBuffer as! MDLMeshBufferData
let d:Data = mdlIndexBufferData.data
let mtlIndexBuffer:MTKMeshBuffer = device.makeBuffer(bytes: ???, length: ???, options:MTLResourceOptions.storageModeShared) as! MTKMeshBuffer
那个???是我需要填补的位。有人可以告诉我正确的 API 用于从 MDL 缓冲区中提取位以填充 MTK 缓冲区吗?
通过尝试从网格中提取数据并将其填充到 Metal 缓冲区中,您实际上是在为自己做更多的工作 "manually"。此外,MTKMeshBuffer
不是 MTLBuffer
— 它 包含 金属缓冲区,以及使用该缓冲区进行渲染时可能需要的信息.
你实际上要做的是让模型 I/O 为你分配 MetalKit 缓冲区 而不是你自己做,这意味着 MetalKit 为数据分配 Metal 缓冲区所以你不必复制它。然后使用 MetalKit 访问网格和缓冲区。像这样的东西(未经测试):
let allocator = MTKMeshBufferAllocator(device: myMetalDevice)
let mdlMesh = MDLMesh(scnGeometry: sceneGeometry, bufferAllocator: allocator)
let mtkMesh = try! MTKMesh(mesh: mdlMesh, device: myMetalDevice)
// ~~~~ <- in real code, please handle errors
// then, at render time...
for (index, vertexBuffer) in mtkMesh.vertexBuffers.enumerated() {
// vertexBuffer is a MTKMeshBuffer, containing an MTLBuffer
renderEncoder.setVertexBuffer(vertexBuffer.buffer,
offset: vertexBuffer.offset,
at: index)
}
for submesh in mtkMesh.submeshes {
// submesh is a MTKSubmesh, containing an MTKMeshBuffer
renderEncoder.drawIndexedPrimitives(type: submesh.primitiveType,
indexCount: submesh.indexCount,
indexType: submesh.indexType,
indexBuffer: submesh.indexBuffer.buffer,
indexBufferOffset: submesh.indexBuffer.offset)
}
解决方案是为每个顶点缓冲区和索引缓冲区构建 MTLBuffers,并在绘制循环中使用它们。工作正常。
参见: https://github.com/turner/HelloMetal 和 运行 Hello SceneKit 目标。