Vulkan Vertex Buffer C

时间:2018-04-11 02:26:44

标签: c buffer shader vulkan

我正在尝试使用C在Vulkan中创建顶点缓冲区。当尝试将顶点数据传递给GPU时,不会显示任何内容。此外,如果启用了验证层,则不会引发任何错误或警告。我曾尝试更改缓冲区大小或使用不同的数据集并检查缓冲区的大小但无济于事。

以下是用于创建缓冲区的相关代码部分。

顶点数据结构:

typedef struct vertexData {
    vec2 pos;
    vec3 color;
} vertexData;

顶点数据:

const vertexData vertices[3] = {
    {{0.0f,-0.5},{1.0f, 0.0f, 0.0f}},
    {{0.5f,0.5},{0.0f, 1.0f, 0.0f}},
    {{-0.5f,0.5},{0.0f, 0.0f, 1.0f}},
};

顶点描述:

static VkVertexInputBindingDescription getBindingDescription() {
    VkVertexInputBindingDescription bindingDescription ={
        .binding = 0,
        .stride = sizeof(vertexData),
        .inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
    };
    return bindingDescription;
}

static VkVertexInputAttributeDescription *getAttributeDescriptions() {
    VkVertexInputAttributeDescription *attributeDescriptions = malloc(2*sizeof(VkVertexInputAttributeDescription));
    attributeDescriptions[0].binding = 0;
    attributeDescriptions[0].location = 0;
    attributeDescriptions[0].format = VK_FORMAT_R32G32_SFLOAT;
    attributeDescriptions[0].offset = offsetof(vertexData, pos);

    attributeDescriptions[1].binding = 0;
    attributeDescriptions[1].location = 1;
    attributeDescriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT;
    attributeDescriptions[1].offset = offsetof(vertexData, color);

    return attributeDescriptions;
}

创建顶点信息:

VkVertexInputBindingDescription bindingDescription = getBindingDescription();
VkVertexInputAttributeDescription *attributeDescriptions;
attributeDescriptions = getAttributeDescriptions();
VkPipelineVertexInputStateCreateInfo vertexInputInfo = {
    .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
    .vertexBindingDescriptionCount = 1,
    .pVertexBindingDescriptions = &bindingDescription,
    .vertexAttributeDescriptionCount = 2,
    .pVertexAttributeDescriptions = attributeDescriptions,
};

创建实际的顶点缓冲区:

void createVertexBuffer() {
    VkBufferCreateInfo bufferInfo = {
        .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
        .size = sizeof(vertices),
        .usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
        .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
    };

    if(vkCreateBuffer(device, &bufferInfo, NULL, &vertexBuffer) != VK_SUCCESS) {
        printf("Failed to create vertex buffer.\n");
        cleanup();
    }

    VkMemoryRequirements memRequirements;
    vkGetBufferMemoryRequirements(device, vertexBuffer, &memRequirements);

    VkMemoryAllocateInfo allocInfo = {
        .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
        .allocationSize = memRequirements.size,
        .memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT),
    };

    if(vkAllocateMemory(device, &allocInfo, NULL, &vertexBufferMemory) != VK_SUCCESS) {
        printf("Failed to allocate vertex buffer memory.\n");
        cleanup();
    }
    vkBindBufferMemory(device, vertexBuffer, vertexBufferMemory, 0);

    void *data;
    vkMapMemory(device, vertexBufferMemory, 0, bufferInfo.size, 0, &data);
        memcpy(data, vertices, sizeof(vertices));
    vkUnmapMemory(device, vertexBufferMemory);
}

最后是实际绘制命令:

vkCmdBindPipeline(commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS,  graphicsPipeline);
    VkBuffer vertexBuffers[] = {vertexBuffer};
    VkDeviceSize offsets[] = {0};
    vkCmdBindVertexBuffers(commandBuffers[i], 0, 1, vertexBuffers, offsets);
    vkCmdDraw(commandBuffers[i], (uint32_t)sizeof(vertices)/sizeof(vertices[0]), 1, 0, 0);

着色器很简单,可以通过着色器。它们在顶点数据硬编码到它们时工作。我能够显示的最多是看起来像屏幕上的垃圾数据,我认为这只是将随机/不正确的内存分配给缓冲区。使用当前状态的代码不会显示任何内容。

感谢任何帮助,谢谢。

0 个答案:

没有答案