gLTF and probably other formats have different "buffers" that are long series of data. Unless the gLTF have a "stride", that is interleaved data, every buffer store things separatly. For example, one buffer have vertex positions, another have normals, a third have UVs and so on.
The implementations I have seen made a struct of this later on that first takes a number of elements of these gLTF buffers and put them together in one struct element. This struct then contains vertex positions, normals, UVs, etc. Then I just put elements of this struct in one SDL vertex buffer that match the shader specified struct.
This seems to be a rather roundabout way to load a mesh to a buffer, can I not directly use the linear buffers specificed in gLTF, without reorder them in a "bundled" struct later on?
If so, how would I tell SDL that here is the vertex positions that match the shader struct, there is the normals and that buffer and so on?
Assume that the shader struct look like this:
struct Input
{
float3 Position : TEXCOORD0
float3 Normal : TEXCOORD1
}
Graphis pipeline defined as:
SDL_GPUGraphicsPipelineCreateInfo pipelineCreateInfo = {
// [...]
.vertex_input_state = (SDL_GPUVertexInputState){
.num_vertex_buffers = 2,
.vertex_buffer_descriptions = (SDL_GPUVertexBufferDescription[]){{
.slot = 0,
.input_rate = SDL_GPU_VERTEXINPUTRATE_VERTEX,
.instance_step_rate = 0,
.pitch = sizeof(float) * 3
},{
.slot = 1,
.input_rate = SDL_GPU_VERTEXINPUTRATE_VERTEX,
.instance_step_rate = 0,
.pitch = sizeof(float) * 3
}},
.num_vertex_attributes = 2,
.vertex_attributes = (SDL_GPUVertexAttribute[]){{
.buffer_slot = 0,
.format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3,
.location = 0,
.offset = 0
}, {
.buffer_slot = 1,
.format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3,
.location = 1,
.offset = 0
}}
// [...]
};
I tried to load the data in different buffers, using code similar to this:
// Create the vertex position buffer
VertexPositionBuffer = SDL_CreateGPUBuffer(
context->Device,
&(SDL_GPUBufferCreateInfo) {
.usage = SDL_GPU_BUFFERUSAGE_VERTEX,
.size = sizeof(float) * vertexPositionsCount // I do not make a struct of 3 floats, instead flatly put all floats in one long series
}
);
// To get data into the vertex buffer, we have to use a transfer buffer
SDL_GPUTransferBuffer* transferPositionBuffer = SDL_CreateGPUTransferBuffer(
context->Device,
&(SDL_GPUTransferBufferCreateInfo) {
.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD,
.size = sizeof(float) * vertexPositionCount
}
);
float* transferPositionData = SDL_MapGPUTransferBuffer(
context->Device,
transferPositionBuffer,
false
);
copyVertexDataToBuffer(transferPositionData);
SDL_UnmapGPUTransferBuffer(context->Device, transferPositionBuffer);
// Do same thing with normals, UVs, etc.
// ... [More code here]
// Upload to GPU
SDL_UploadToGPUBuffer(
copyPass,
&(SDL_GPUTransferBufferLocation) {
.transfer_buffer = transferPositionBuffer,
.offset = 0
},
&(SDL_GPUBufferRegion) {
.buffer = VertexPositionBuffer,
.offset = 0,
.size = sizeof(float) * vertexPositionCount
},
false
);
// Upload other data in similar way
However I got stuck when I try to render this:
// Can I use several suffers here, if so, how do I tell SDL what is what in the shader struct?
SDL_BindGPUVertexBuffers(renderPass, 0, &(SDL_GPUBufferBinding){
.buffer = VertexPositionBuffer,
.offset = 0
}, 1);
SDL_DrawGPUPrimitives(renderPass, 3, 1, 0, 0);