Search code examples
iosmetalmetalkit

Mesh in Metal IOS


I am new to MTKMesh/MDLMesh any online resource material to create a Creating a Custom Mesh in 2D. I have the Vertex data.

init(vertexBuffer: MDLMeshBuffer, vertexCount: Int,  descriptor: MDLVertexDescriptor, submeshes: [MDLSubmesh])

I hope to use this function. Any suggestion to create MDLMeshBuffer,MDLVertexDescriptor, Submeshes


Solution

  • Suppose you have a Vertex struct with a single float2 member representing position. You might start with an array of such vertices ([Vertex]) and an array of 16-bit unsigned integer indices ([UInt16]).

    Then you might do something like this:

    let device = MTLCreateSystemDefaultDevice()!
    let allocator = MTKMeshBufferAllocator(device: device)
    
    let vertexBuffer = allocator.newBuffer(MemoryLayout<Vertex>.stride * vertices.count, type: .vertex)
    let vertexMap = vertexBuffer.map()
    vertexMap.bytes.assumingMemoryBound(to: Vertex.self).assign(from: vertices, count: vertices.count)
    
    let indexBuffer = allocator.newBuffer(MemoryLayout<UInt16>.stride * indices.count, type: .index)
    let indexMap = indexBuffer.map()
    indexMap.bytes.assumingMemoryBound(to: UInt16.self).assign(from: indices, count: indices.count)
    
    let submesh = MDLSubmesh(indexBuffer: indexBuffer,
                             indexCount: indices.count,
                             indexType: .uInt16,
                             geometryType: .triangles,
                             material: nil)
    
    let vertexDescriptor = MDLVertexDescriptor()
    vertexDescriptor.attributes[0] = MDLVertexAttribute(name: MDLVertexAttributePosition,
                                                        format: .float2,
                                                        offset: 0,
                                                        bufferIndex: 0)
    let mdlMesh = MDLMesh(vertexBuffer: vertexBuffer,
                          vertexCount: vertices.count,
                          descriptor: vertexDescriptor, 
                          submeshes: [submesh])
    
    let mesh = try? MTKMesh(mesh: mdlMesh, device: device)
    

    If your vertex type is more complex, you'd adjust the vertex descriptor accordingly.