Vulkan入门(11)-顶点输入描述及顶点缓冲的创建.md

本文介绍了如何在Vulkan中创建和管理顶点数据,包括顶点输入描述、顶点缓冲区创建、内存分配以及如何将顶点数据复制到GPU内存。通过VkVertexInputBindingDescription和VkVertexInputAttributeDescription结构体设置顶点数据格式,并通过VkBuffer和内存分配将数据传输到GPU。最后,展示了如何在渲染过程中绑定顶点缓冲区。
摘要由CSDN通过智能技术生成

参考资料

简述

接下来,我们将用内存中的顶点缓冲区替换顶点着色器中的硬编码顶点数据。我们将从创建CPU可见缓冲区的最简单方法开始,并使用memcpy将顶点数据直接复制到其中,然后我们将看到如何使用分段缓冲区将顶点数据复制到高性能内存。

首先修改顶点着色器不再包含顶点数据在着色器代码本身, 顶点着色器使用in关键字从顶点缓冲区获取输入。

#version 450
#extension GL_ARB_separate_shader_objects : enable

layout(location = 0) in vec2 inPosition;
layout(location = 1) in vec3 inColor;

// 输出为fragColor
layout(location = 0) out vec3 fragColor;

void main() {
    gl_Position = vec4(inPosition, 0.0, 1.0);
    fragColor = inColor;
}

inPosition和inColor变量是顶点属性。 它们是在顶点缓冲区中为每个顶点指定的属性,就像我们使用两个数组为每个顶点手动指定位置和颜色一样。 更改后记得重新编译顶点着色器!

像fragColor一样,layout(location = x)批注为输入分配索引,我们之后可以使用索引来引用它们。 重要的是要知道某些类型(例如dvec3 64位向量)使用多个插槽。 这意味着之后的索引必须至少高2倍(这里没搞懂, 需要学习一下GLSL的语法:https://www.khronos.org/opengl/wiki/Layout_Qualifier_(GLSL)):

layout(location = 0) in dvec3 inPosition;
layout(location = 2) in vec3 inColor;

一. 顶点数据

将顶点数据从着色器代码移动到程序代码中的数组中。需要引入GLM库,它为我们提供了与线性代数相关的类型,如向量和矩阵, 有与着色器语言中使用的向量类型完全匹配的c++类型。我们将使用这些类型来指定位置和颜色向量。

#include <glm/glm.hpp>

struct Vertex {
    glm::vec2 pos;
    glm::vec3 color;
};

const std::vector<Vertex> vertices = {
    {
  {0.0f, -0.5f}, {1.0f, 0.0f, 0.0f}},
    {
  {0.5f, 0.5f}, {0.0f, 1.0f, 0.0f}},
    {
  {-0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}}
};

创建一个名为Vertex的新结构,内有两个属性,我们将在其内部的顶点着色器中使用. 使用顶点结构来指定顶点数据的数组。我们使用和之前完全相同的位置和颜色值,但现在它们被组合到一个顶点数组中, 这就是所谓的交错顶点(interleaving vertex)属性。

接下来是告诉Vulkan,一旦数据格式被上传到GPU内存,如何将其传递到顶点着色器。而传达这个信息需要有两种类型的结构: VkVertexInputBindingDescription和VkVertexInputAttributeDescription.

1.1 绑定描述

第一个结构是VkVertexInputBindingDescription,我们将向顶点结构添加一个成员函数,用正确的数据填充它。

struct Vertex {
    glm::vec2 pos;
    glm::vec3 color;

    static VkVertexInputBindingDescription getBindingDescription() {
        VkVertexInputBindingDescription bindingDescription = {};
        return bindingDescription;
    }
};

1.1.1 VkVertexInputBindingDescription

typedef struct VkVertexInputBindingDescription {
    uint32_t             binding;
    uint32_t             stride;
    VkVertexInputRate    inputRate;
} VkVertexInputBindingDescription;
  1. binding: 该结构描述的绑定号
  2. stride : 是缓冲区中两个连续元素之间的距离(以字节为单位)
  3. inputRate: 是一个VkVertexInputRate值,指定顶点属性寻址是顶点索引还是实例索引的函数
    1. VK_VERTEX_INPUT_RATE_VERTEX: 指定顶点属性寻址是顶点索引的函数,即移动到每个顶点后的下一个数据项
    2. VK_VERTEX_INPUT_RATE_INSTANCE: 指定顶点属性寻址是实例索引的函数,即移到每个实例之后的下一个数据项

顶点绑定描述在所有顶点中从内存加载数据的速率。它指定数据条目之间的字节数,以及是在每个顶点之后还是在每个实例之后移动到下一个数据条目。

1.1.2 绑定

所有的顶点数据都打包在一个数组中,所以我们只需要一个绑定:

    static VkVertexInputBindingDescription getBindingDescription() {
        VkVertexInputBindingDescription bindingDescription = {};

        VkVertexInputBindingDescription bindingDescription = {};
        bindingDescription.binding = 0;
        bindingDescription.stride = sizeof(Vertex);
        bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;

        return bindingDescription;
    }

1.2 属性描述

第二个描述如何处理顶点输入的结构是VkVertexInputAttributeDescription。我们将添加另一个辅助函数到顶点来填充这些结构体。

#include <array>

struct Vertex {
    glm::vec2 pos;
    glm::vec3 color;

    static VkVertexInputBindingDescription getBindingDescription() {
        VkVertexInputBindingDescription bindingDescription = {};
        return bindingDescription;
    }

    static std::array<VkVertexInputAttributeDescription, 2> getAttributeDescriptions() {
        std::array<VkVertexInputAttributeDescription, 2> attributeDescriptions = {};
        return attributeDescriptions;
    }
};

正如函数原型所表明的,有两个VkVertexInputAttributeDescription,分别代表位置和颜色。

属性描述结构描述如何从源自绑定描述的顶点数据块中提取顶点属性。

1.2.1 VkVertexInputAttributeDescription

typedef struct VkVertexInputAttributeDescription {
    uint32_t    location;
    uint32_t    binding;
    VkFormat    format;
    uint32_t    offset;
} VkVertexInputAttributeDescription;
  1. location: 属性的着色器绑定位置号
  2. binding: 该属性获取其数据的绑定号
  3. format: 指顶点属性数据的大小和类型, 应使用颜色通道数量与
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值