如何从 MDLMeshBufferData 中提取数据来填充 MTKMeshBuffer?

问题描述 投票:0回答:2

我需要从 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

那个???是我需要填充的位。有人可以向我展示用于从 MDL 缓冲区提取位以填充 MTK 缓冲区的正确 API 吗?

swift metal metalkit modelio
2个回答
2
投票

通过尝试从网格中提取数据并将其“手动”填充到 Metal 缓冲区中,您实际上是在为自己做更多的工作。此外,

MTKMeshBuffer
不是
MTLBuffer
— 它包含一个 Metal 缓冲区,以及使用该缓冲区进行渲染时可能需要的信息。

您实际上要做的是让 Model 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) }
    

1
投票
解决方案是为每个 vertexBuffer 和 indexBuffer 构建 MTLBuffer 并在绘制循环中使用它们。效果很好。

参见:

https://github.com/turner/HelloMetal 并运行 HelloSceneKit 目标。

© www.soinside.com 2019 - 2024. All rights reserved.