Adding support for glTF meshes without indices

I have pushed an update to my Vulkan glTF PBR 2.0 application that adds support for rendering primitives without indices. Up until now, all primitives of a glTFs scene had to come with indices to be rendered by the application, which is usually the case for more complex scenes.

After getting a request for this, and checking with the glTF 2.0 spec, primitives without indices are actually a valid glTF 2.0 use-case.

Getting this to work was actually straight forward.

Model loader (VulkanglTFModel.hpp)

Aside from removing some asserts that would check for vertexCount and indexCount to be > 0 and then only creating and staging the index buffer if indices are present:

1
2
3
4
if (indexBufferSize > 0) {
    copyRegion.size = indexBufferSize;
    vkCmdCopyBuffer(copyCmd, indexStaging.buffer, indices.buffer, 1, &copyRegion);
}

I have also added the new hasIndices and vertexCount properties to the primitive class of the loader to be used for drawing the primitives.

406
407
408
409
410
411
412
413
struct Primitive {
    uint32_t firstIndex;
    uint32_t indexCount;
    uint32_t vertexCount;
    Material &material;
    bool hasIndices;
    ...
}

Application

If you’re using the model loader, and want to support models without indices, you simply have to change your draw routine to either use vkCmdDraw or vkCmdDrawIndexed depending on the new hasIndices property of the mesh you want to render:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
if (node->mesh) {
    for (vkglTF::Primitive *primitive : node->mesh->primitives) {
        ...
        if (primitive->hasIndices) {
            vkCmdDrawIndexed(commandBuffer, primitive->indexCount, 1, primitive->firstIndex, 0, 0);
        } else {
            vkCmdDraw(commandBuffer, primitive->vertexCount, 1, 0, 0);
        }
    }
}

In motion

While not an actual PBR model, here is a short video of demonstrating an animated, low-poly model that does not have indices.