Code cleanup and readme for vertex attributes sample
This commit is contained in:
parent
e34634c266
commit
6b0bc52a1b
4 changed files with 77 additions and 19 deletions
|
|
@ -2,4 +2,60 @@
|
||||||
|
|
||||||
## Synopsis
|
## Synopsis
|
||||||
|
|
||||||
This sample demonstrates how to pass vertex attributes using interleaved or separate buffers.
|
This sample demonstrates two different ways of providing vertex data to the GPU using either interleaved or separate buffers for vertex attributes.
|
||||||
|
|
||||||
|
## Shader interface
|
||||||
|
|
||||||
|
The shader interface for passing the vertex attributes is the same, no matter if the data provided is coming from a single interleaved or multiple separate buffers.
|
||||||
|
|
||||||
|
```glsl
|
||||||
|
layout (location = 0) in vec3 inPos;
|
||||||
|
layout (location = 1) in vec3 inNormal;
|
||||||
|
layout (location = 2) in vec2 inUV;
|
||||||
|
layout (location = 3) in vec4 inTangent;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Interleaved vertex attributes
|
||||||
|
|
||||||
|
In an interleaved vertex buffer, the components that make up a single vertex are stored after each other, so the stride of a single vertex is the sum of it's component's sizes.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// Binding
|
||||||
|
const std::vector<VkVertexInputBindingDescription> vertexInputBindingsInterleaved = {
|
||||||
|
{ 0, sizeof(Vertex), VK_VERTEX_INPUT_RATE_VERTEX },
|
||||||
|
};
|
||||||
|
|
||||||
|
// Attribute
|
||||||
|
const std::vector<VkVertexInputAttributeDescription> vertexInputAttributesInterleaved = {
|
||||||
|
{ 0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(Vertex, pos) },
|
||||||
|
{ 1, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(Vertex, normal) },
|
||||||
|
{ 2, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(Vertex, uv) },
|
||||||
|
{ 3, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(Vertex, tangent) },
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Separate vertex attributes
|
||||||
|
|
||||||
|
When using separate buffers, each component is stored in it's own buffer. So e.g. the position buffer only contains vertex positions stored consecutively.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// Bindings
|
||||||
|
const std::vector<VkVertexInputBindingDescription> vertexInputBindingsSeparate = {
|
||||||
|
{ 0, sizeof(glm::vec3), VK_VERTEX_INPUT_RATE_VERTEX },
|
||||||
|
{ 1, sizeof(glm::vec3), VK_VERTEX_INPUT_RATE_VERTEX },
|
||||||
|
{ 2, sizeof(glm::vec2), VK_VERTEX_INPUT_RATE_VERTEX },
|
||||||
|
{ 3, sizeof(glm::vec4), VK_VERTEX_INPUT_RATE_VERTEX },
|
||||||
|
};
|
||||||
|
|
||||||
|
// Attributes
|
||||||
|
const std::vector<VkVertexInputAttributeDescription> vertexInputAttributesSeparate = {
|
||||||
|
{ 0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0 },
|
||||||
|
{ 1, 1, VK_FORMAT_R32G32B32_SFLOAT, 0 },
|
||||||
|
{ 2, 2, VK_FORMAT_R32G32_SFLOAT, 0 },
|
||||||
|
{ 3, 3, VK_FORMAT_R32G32B32A32_SFLOAT, 0 },
|
||||||
|
};
|
||||||
|
```
|
||||||
BIN
examples/vertexattributes/interleavedbuffer.png
Normal file
BIN
examples/vertexattributes/interleavedbuffer.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.3 KiB |
BIN
examples/vertexattributes/separatebuffers.png
Normal file
BIN
examples/vertexattributes/separatebuffers.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
|
|
@ -230,7 +230,8 @@ void VulkanExample::buildCommandBuffers()
|
||||||
VkDeviceSize offsets[4] = { 0, 0, 0, 0 };
|
VkDeviceSize offsets[4] = { 0, 0, 0, 0 };
|
||||||
std::array<VkBuffer, 4> buffers = { separateVertexBuffers.pos.buffer, separateVertexBuffers.normal.buffer, separateVertexBuffers.uv.buffer, separateVertexBuffers.tangent.buffer };
|
std::array<VkBuffer, 4> buffers = { separateVertexBuffers.pos.buffer, separateVertexBuffers.normal.buffer, separateVertexBuffers.uv.buffer, separateVertexBuffers.tangent.buffer };
|
||||||
vkCmdBindVertexBuffers(drawCmdBuffers[i], 0, static_cast<uint32_t>(buffers.size()), buffers.data(), offsets);
|
vkCmdBindVertexBuffers(drawCmdBuffers[i], 0, static_cast<uint32_t>(buffers.size()), buffers.data(), offsets);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// Using interleaved attribute bindings only requires one buffer to be bound
|
// Using interleaved attribute bindings only requires one buffer to be bound
|
||||||
VkDeviceSize offsets[1] = { 0 };
|
VkDeviceSize offsets[1] = { 0 };
|
||||||
vkCmdBindVertexBuffers(drawCmdBuffers[i], 0, 1, &interleavedVertexBuffer.buffer, offsets);
|
vkCmdBindVertexBuffers(drawCmdBuffers[i], 0, 1, &interleavedVertexBuffer.buffer, offsets);
|
||||||
|
|
@ -492,13 +493,13 @@ void VulkanExample::preparePipelines()
|
||||||
// Interleaved vertex attributes
|
// Interleaved vertex attributes
|
||||||
// One Binding (one buffer) and multiple attributes
|
// One Binding (one buffer) and multiple attributes
|
||||||
const std::vector<VkVertexInputBindingDescription> vertexInputBindingsInterleaved = {
|
const std::vector<VkVertexInputBindingDescription> vertexInputBindingsInterleaved = {
|
||||||
vks::initializers::vertexInputBindingDescription(0, sizeof(Vertex), VK_VERTEX_INPUT_RATE_VERTEX),
|
{ 0, sizeof(Vertex), VK_VERTEX_INPUT_RATE_VERTEX },
|
||||||
};
|
};
|
||||||
const std::vector<VkVertexInputAttributeDescription> vertexInputAttributesInterleaved = {
|
const std::vector<VkVertexInputAttributeDescription> vertexInputAttributesInterleaved = {
|
||||||
vks::initializers::vertexInputAttributeDescription(0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(Vertex, pos)),
|
{ 0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(Vertex, pos) },
|
||||||
vks::initializers::vertexInputAttributeDescription(0, 1, VK_FORMAT_R32G32B32_SFLOAT, offsetof(Vertex, normal)),
|
{ 1, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(Vertex, normal) },
|
||||||
vks::initializers::vertexInputAttributeDescription(0, 2, VK_FORMAT_R32G32_SFLOAT, offsetof(Vertex, uv)),
|
{ 2, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(Vertex, uv) },
|
||||||
vks::initializers::vertexInputAttributeDescription(0, 3, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(Vertex, tangent)),
|
{ 3, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(Vertex, tangent) },
|
||||||
};
|
};
|
||||||
|
|
||||||
vertexInputStateCI = vks::initializers::pipelineVertexInputStateCreateInfo(vertexInputBindingsInterleaved, vertexInputAttributesInterleaved);
|
vertexInputStateCI = vks::initializers::pipelineVertexInputStateCreateInfo(vertexInputBindingsInterleaved, vertexInputAttributesInterleaved);
|
||||||
|
|
@ -507,17 +508,18 @@ void VulkanExample::preparePipelines()
|
||||||
// Separate vertex attribute
|
// Separate vertex attribute
|
||||||
// Multiple bindings (for each attribute buffer) and multiple attribues
|
// Multiple bindings (for each attribute buffer) and multiple attribues
|
||||||
const std::vector<VkVertexInputBindingDescription> vertexInputBindingsSeparate = {
|
const std::vector<VkVertexInputBindingDescription> vertexInputBindingsSeparate = {
|
||||||
vks::initializers::vertexInputBindingDescription(0, sizeof(glm::vec3), VK_VERTEX_INPUT_RATE_VERTEX),
|
{ 0, sizeof(glm::vec3), VK_VERTEX_INPUT_RATE_VERTEX },
|
||||||
vks::initializers::vertexInputBindingDescription(1, sizeof(glm::vec3), VK_VERTEX_INPUT_RATE_VERTEX),
|
{ 1, sizeof(glm::vec3), VK_VERTEX_INPUT_RATE_VERTEX },
|
||||||
vks::initializers::vertexInputBindingDescription(2, sizeof(glm::vec2), VK_VERTEX_INPUT_RATE_VERTEX),
|
{ 2, sizeof(glm::vec2), VK_VERTEX_INPUT_RATE_VERTEX },
|
||||||
vks::initializers::vertexInputBindingDescription(3, sizeof(glm::vec4), VK_VERTEX_INPUT_RATE_VERTEX),
|
{ 3, sizeof(glm::vec4), VK_VERTEX_INPUT_RATE_VERTEX },
|
||||||
};
|
};
|
||||||
const std::vector<VkVertexInputAttributeDescription> vertexInputAttributesSeparate = {
|
const std::vector<VkVertexInputAttributeDescription> vertexInputAttributesSeparate = {
|
||||||
vks::initializers::vertexInputAttributeDescription(0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0),
|
{ 0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0 },
|
||||||
vks::initializers::vertexInputAttributeDescription(1, 1, VK_FORMAT_R32G32B32_SFLOAT, 0),
|
{ 1, 1, VK_FORMAT_R32G32B32_SFLOAT, 0 },
|
||||||
vks::initializers::vertexInputAttributeDescription(2, 2, VK_FORMAT_R32G32_SFLOAT, 0),
|
{ 2, 2, VK_FORMAT_R32G32_SFLOAT, 0 },
|
||||||
vks::initializers::vertexInputAttributeDescription(3, 3, VK_FORMAT_R32G32B32A32_SFLOAT, 0),
|
{ 3, 3, VK_FORMAT_R32G32B32A32_SFLOAT, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
vertexInputStateCI = vks::initializers::pipelineVertexInputStateCreateInfo(vertexInputBindingsSeparate, vertexInputAttributesSeparate);
|
vertexInputStateCI = vks::initializers::pipelineVertexInputStateCreateInfo(vertexInputBindingsSeparate, vertexInputAttributesSeparate);
|
||||||
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.vertexAttributesSeparate));
|
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.vertexAttributesSeparate));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue