Alex Dart Stewie
Alex Dart Stewie

Reputation: 1

How describe tightly packed vertices data in Apple Metal?

I'm transferring my program from opengl to metal. In the original I use tightly packed vertex data, which there are no problems with describing in opengle, but in metal it doesn’t work. Tightly packed data in my opinion is: [x,y,z, ... x,y,z, nx,ny,nz, ... nx,ny,nz, r,g,b, ... r,g,b], normal packed data is [x,y,z,nx,ny,nz,r,g,b ... x,y,z,nx,ny,nz,r,g,b], where x,y,z - coordinates, nx,ny,nz - normals and r,g,b - colors. In opengl I set stride to zero (or step in bytes between vertices within the same data type) and offset for the beginning of each data. But here I get an error. Code

        let vertices: [Float32] = [...]
        vbuffer = device.makeBuffer(bytes: vertices, length: vertices.count * MemoryLayout<Float32>.size, options: [])!

        vertexDescriptor = MTLVertexDescriptor()
        vertexDescriptor.attributes[0].format = .float3
        vertexDescriptor.attributes[0].offset = 0
        vertexDescriptor.attributes[0].bufferIndex = 0
        vertexDescriptor.attributes[1].format = .float3
        vertexDescriptor.attributes[1].offset = MemoryLayout<Float>.size * vertices.count / 2 //half of vertex buffer, for this buffer contains only positions and colors
        vertexDescriptor.attributes[1].bufferIndex = 0
        vertexDescriptor.layouts[0].stride = MemoryLayout<Float>.size * 3
        vertexDescriptor.layouts[0].stepRate = 1
        vertexDescriptor.layouts[0].stepFunction = .perVertex
        vertexDescriptor.layouts[1].stride = MemoryLayout<Float>.size * 3
        vertexDescriptor.layouts[1].stepRate = 1
        vertexDescriptor.layouts[1].stepFunction = .perVertex

error

validateVertexAttribute, line 724: error 'Attribute at index 1: the attribute offset (48) + attribute size (12) must be <= the stride of the buffer (12) at buffer index 0.'

I don't understand how to solve my problem. How to describe this data? Mixing data will be inconvenient, time-consuming and resource-intensive. Using different buffers is also not very advisable

Upvotes: 0

Views: 47

Answers (1)

Alex Dart Stewie
Alex Dart Stewie

Reputation: 1

As always, it’s worth asking a question, so I find the answer myself

        vertexDescriptor = MTLVertexDescriptor()
        vertexDescriptor.attributes[0].format = .float3
        vertexDescriptor.attributes[0].offset = 0
        vertexDescriptor.attributes[0].bufferIndex = 0
        vertexDescriptor.attributes[1].format = .float3
        vertexDescriptor.attributes[1].offset = 0
        vertexDescriptor.attributes[1].bufferIndex = 1
        vertexDescriptor.layouts[0].stride = MemoryLayout<Float32>.size * 3
        vertexDescriptor.layouts[1].stride = MemoryLayout<Float32>.size * 3

//where draw
            commandEncoder.setVertexBuffer(vbuffer, offset: 0, index: 0)
            commandEncoder.setVertexBuffer(vbuffer, offset: MemoryLayout<Float>.size * vertices.count / 2, index: 1)

Upvotes: 0

Related Questions