如何使用 Metal 渲染多个 triangleStrip?

How to render multiple triangleStrips using Metal?

现在我已经知道如何在 Metal 中渲染多个三角形了:

let vertexBuffer = device.makeBuffer(vertices_triangles)
renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, index: 0)
renderEncoder.drawPrimitives(type: .triangleStrip, vertexStart: 0, vertexCount: vertices_triangles.count)
renderEncoder.endEncoding()
commandBuffer.present(view.currentDrawable!)
commandBuffer.commit()

这里,vertices_triangles 是元素 VertexArray。相邻的三个顶点显示一个要渲染的三角形。

但是,我真的不知道如何在 Metal 中渲染多个 triangleStrip。

let vertexBuffer = device.makeBuffer(vertices_triangleStrips)
renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, index: 0)
renderEncoder.drawPrimitives(type: .triangleStrip, vertexStart: 0, vertexCount: vertices_triangleStrips.count)

如果我将相邻的顶点放在vertices_triangleStrips中并将renderEncoder.drawPrimitives.type设置为.triangleStrip,我将得到一个 triangleStrip。 但是如何渲染多个 triangleStrips?我尝试使用 for 循环制作多个顶点缓冲区并使用 renderEncoder.drawPrimitives 绘制每个 triangleStrip。出于性能原因,这样做似乎不是一个好主意。

参考 Metal 中的 documentation of drawIndexedPrimitives(type:indexCount:indexType:indexBuffer:indexBufferOffset:instanceCount:baseVertex:baseInstance:)

Primitive restart functionality is enabled with the largest unsigned integer index value, relative to indexType (0xFFFF for MTLIndexTypeUInt16 or 0xFFFFFFFF for MTLIndexTypeUInt32). This feature finishes drawing the current primitive at the specified index and starts drawing a new one with the next index.

您可以通过定义由 0xFFFF0xFFFFFFFF 分隔的 indexBuffer 来呈现多个 triangleStrip。

例如。在顶点 [0,1,2,3] [4,5,6,7] [8,9,10] [11,12,13,14,15,16]

渲染 triangleStrips
let indexBytes: [UInt32] = [0, 1, 2, 3, 0xFFFFFFFF, 4, 5, 6, 7, 0xFFFFFFFF, 8, 9, 10, 0xFFFFFFFF, 11, 12, 13, 14, 15, 16, 0xFFFFFFFF]

let vertexBuffer = device.makeBuffer(bytes: vertices_triangleStrips,
                                     length: vertices_triangleStrips.count * MemoryLayout<MetalPosition2>.stride,
                                     options: [])!
let indexBuffer = device.makeBuffer(bytes: indexBytes,
                                    length: indexBytes.count * MemoryLayout<UInt32>.stride,
                                    options: [])!

renderEncoder.setVertexBuffer(vertexBuffer,
                              offset: 0,
                              index: 0)
renderEncoder.drawIndexedPrimitives(type: .triangleStrip,
                                    indexCount: indexBytes.count,
                                    indexType: .uint32,
                                    indexBuffer: indexBuffer,
                                    indexBufferOffset: 0) // only one instance