Reputation: 1
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
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