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

时间:2016-11-17 18:46:49

标签: metal modelio metalkit

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

2 个答案:

答案 0 :(得分:1)

您实际上是通过尝试从网格中提取数据并将其“手动”填充到金属缓冲区中来为自己做更多的工作。此外,MTKMeshBuffer不是MTLBuffer - 包含金属缓冲区,以及使用该缓冲区进行渲染时可能需要的信息。

你真正要做的是让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 :(得分:1)

解决方案是为vertexBuffer和indexBuffer中的每一个构建MTLBuffers,并在draw循环中使用它们。工作正常。

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