2016-11-17 3 views
1

Je dois créer une instance MTKMeshBuffer à partir d'une instance MDLMeshBufferData. Voici un extrait de code:Comment extraire les données d'un MDLMeshBufferData pour remplir un 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 

Le ??? sont les bits que je dois remplir. Quelqu'un peut-il me montrer la bonne API à utiliser pour extraire les bits du tampon MDL pour remplir le tampon MTK?

Répondre

1

La solution consiste à construire les MTLBuffers pour chacun des VertexBuffer et IndexBuffer et de les utiliser dans la boucle de tirage. Fonctionne bien. Voir: https://github.com/turner/HelloMetal et exécutez la cible HelloSceneKit.

1

Vous faites en réalité plus de travail en essayant d'extraire les données du maillage et de les placer dans les tampons Metal "manuellement". En outre, un MTKMeshBuffer n'est pas un MTLBuffer - il contient un tampon de métal, avec des informations dont vous aurez probablement besoin lors de l'utilisation de ce tampon pour le rendu.

Qu'est-ce que vous avez réellement ce qu'il faut faire ici est d'avoir Model E/S allouer des tampons de MetalKit pour vous au lieu de le faire vous-même, ce qui signifie MetalKit alloue des tampons métalliques pour les données de sorte que vous ne disposez pas de le copier. Ensuite, utilisez MetalKit pour accéder aux maillages et aux tampons. Quelque chose comme cela (non testé):

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) 
} 
+0

Oui, j'ai réussi à créer des maillages via les méthodes d'usine MDLMesh - plan/cube/sphere/... Fonctionne très bien. Ma motivation pour construire les buffers - indexBuffer et vertexBuffer à partir de rien est de lire dans un fichier SCNScene - .scn - et d'en extraire des mailles. La clé API - MDLMesh (scnGeometry: sceneGeometry, bufferAllocator: MTKMeshBufferAllocator (périphérique: périphérique)) - est cassée et je vais y déposer un bug radar. Essayez-le vous-même. – dugla