最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c - Can I with SDL3 GPU load vertexes, normals, colours, UVs in different buffers? - Stack Overflow

programmeradmin3浏览0评论

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);
发布评论

评论列表(0)

  1. 暂无评论