Reputation: 12954
I need to create a MTKMeshBuffer instance from a MDLMeshBufferData instance. Here is a code snippet:
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
The ??? are the bits I need to fill. Can someone please show me the proper API to use to extract the bits from the MDL buffer to fill the MTK buffer?
Upvotes: 3
Views: 1700
Reputation: 12954
The solution is to build the MTLBuffers for each of vertexBuffer and indexBuffer and use them in the draw loop. Works fine.
See: https://github.com/turner/HelloMetal and run the HelloSceneKit target.
Upvotes: 1
Reputation: 126167
You're actually making more work for yourself by trying to pull data out of the mesh and stuff it into Metal buffers "manually". Also, an MTKMeshBuffer
is not an MTLBuffer
— it contains a Metal buffer, along with info that you're likely to need when using that buffer to render with.
What you actually what to do here is have Model I/O allocate MetalKit buffers for you instead of doing it yourself, which means MetalKit allocates Metal buffers for the data so you don't have to copy it. Then use MetalKit to access the meshes and buffers. Something like this (untested):
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)
}
Upvotes: 2