Reworked texture array sample, code cleanup. refactoring

This commit is contained in:
Sascha Willems 2019-04-13 13:38:17 +02:00
parent a44c09155b
commit a3c2f42859
4 changed files with 97 additions and 200 deletions

View file

@ -1,6 +1,6 @@
#version 450 #version 450
layout (location = 0) in vec4 inPos; layout (location = 0) in vec3 inPos;
layout (location = 1) in vec2 inUV; layout (location = 1) in vec2 inUV;
struct Instance struct Instance
@ -22,5 +22,5 @@ void main()
{ {
outUV = vec3(inUV, ubo.instance[gl_InstanceIndex].arrayIndex.x); outUV = vec3(inUV, ubo.instance[gl_InstanceIndex].arrayIndex.x);
mat4 modelView = ubo.view * ubo.instance[gl_InstanceIndex].model; mat4 modelView = ubo.view * ubo.instance[gl_InstanceIndex].model;
gl_Position = ubo.projection * modelView * inPos; gl_Position = ubo.projection * modelView * vec4(inPos, 1.0);
} }

View file

@ -1,7 +1,7 @@
/* /*
* Vulkan Example - Texture arrays and instanced rendering * Vulkan Example - Texture arrays and instanced rendering
* *
* Copyright (C) 2016 by Sascha Willems - www.saschawillems.de * Copyright (C) Sascha Willems - www.saschawillems.de
* *
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
*/ */
@ -23,7 +23,6 @@
#include "VulkanTexture.hpp" #include "VulkanTexture.hpp"
#include "VulkanBuffer.hpp" #include "VulkanBuffer.hpp"
#define VERTEX_BUFFER_BIND_ID 0
#define ENABLE_VALIDATION false #define ENABLE_VALIDATION false
// Vertex layout for this example // Vertex layout for this example
@ -40,12 +39,6 @@ public:
uint32_t layerCount; uint32_t layerCount;
vks::Texture textureArray; vks::Texture textureArray;
struct {
VkPipelineVertexInputStateCreateInfo inputState;
std::vector<VkVertexInputBindingDescription> bindingDescriptions;
std::vector<VkVertexInputAttributeDescription> attributeDescriptions;
} vertices;
vks::Buffer vertexBuffer; vks::Buffer vertexBuffer;
vks::Buffer indexBuffer; vks::Buffer indexBuffer;
uint32_t indexCount; uint32_t indexCount;
@ -78,11 +71,12 @@ public:
VulkanExample() : VulkanExampleBase(ENABLE_VALIDATION) VulkanExample() : VulkanExampleBase(ENABLE_VALIDATION)
{ {
zoom = -15.0f;
rotationSpeed = 0.25f;
rotation = { -15.0f, 35.0f, 0.0f };
title = "Texture arrays"; title = "Texture arrays";
settings.overlay = true; settings.overlay = true;
camera.type = Camera::CameraType::lookat;
camera.setPosition(glm::vec3(0.0f, 0.0f, -7.5f));
camera.setRotation(glm::vec3(-35.0f, 0.0f, 0.0f));
camera.setPerspective(45.0f, (float)width / (float)height, 0.1f, 256.0f);
} }
~VulkanExample() ~VulkanExample()
@ -90,7 +84,6 @@ public:
// Clean up used Vulkan resources // Clean up used Vulkan resources
// Note : Inherited destructor cleans up resources stored in base class // Note : Inherited destructor cleans up resources stored in base class
// Clean up texture resources
vkDestroyImageView(device, textureArray.view, nullptr); vkDestroyImageView(device, textureArray.view, nullptr);
vkDestroyImage(device, textureArray.image, nullptr); vkDestroyImage(device, textureArray.image, nullptr);
vkDestroySampler(device, textureArray.sampler, nullptr); vkDestroySampler(device, textureArray.sampler, nullptr);
@ -340,7 +333,7 @@ public:
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
VkDeviceSize offsets[1] = { 0 }; VkDeviceSize offsets[1] = { 0 };
vkCmdBindVertexBuffers(drawCmdBuffers[i], VERTEX_BUFFER_BIND_ID, 1, &vertexBuffer.buffer, offsets); vkCmdBindVertexBuffers(drawCmdBuffers[i], 0, 1, &vertexBuffer.buffer, offsets);
vkCmdBindIndexBuffer(drawCmdBuffers[i], indexBuffer.buffer, 0, VK_INDEX_TYPE_UINT32); vkCmdBindIndexBuffer(drawCmdBuffers[i], indexBuffer.buffer, 0, VK_INDEX_TYPE_UINT32);
vkCmdDrawIndexed(drawCmdBuffers[i], indexCount, layerCount, 0, 0, 0); vkCmdDrawIndexed(drawCmdBuffers[i], indexCount, layerCount, 0, 0, 0);
@ -353,31 +346,53 @@ public:
} }
} }
void generateQuad() void generateCube()
{ {
// Setup vertices for a single uv-mapped quad made from two triangles std::vector<Vertex> vertices = {
std::vector<Vertex> vertices = { { -1.0f, -1.0f, 1.0f }, { 0.0f, 0.0f } },
{ { { 1.0f, -1.0f, 1.0f }, { 1.0f, 0.0f } },
{ { 2.5f, 2.5f, 0.0f }, { 1.0f, 1.0f } }, { { 1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f } },
{ { -2.5f, 2.5f, 0.0f }, { 0.0f, 1.0f } }, { { -1.0f, 1.0f, 1.0f }, { 0.0f, 1.0f } },
{ { -2.5f, -2.5f, 0.0f }, { 0.0f, 0.0f } },
{ { 2.5f, -2.5f, 0.0f }, { 1.0f, 0.0f } } { { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f } },
{ { 1.0f, 1.0f, -1.0f }, { 1.0f, 0.0f } },
{ { 1.0f, -1.0f, -1.0f }, { 1.0f, 1.0f } },
{ { 1.0f, -1.0f, 1.0f }, { 0.0f, 1.0f } },
{ { -1.0f, -1.0f, -1.0f }, { 0.0f, 0.0f } },
{ { 1.0f, -1.0f, -1.0f }, { 1.0f, 0.0f } },
{ { 1.0f, 1.0f, -1.0f }, { 1.0f, 1.0f } },
{ { -1.0f, 1.0f, -1.0f }, { 0.0f, 1.0f } },
{ { -1.0f, -1.0f, -1.0f }, { 0.0f, 0.0f } },
{ { -1.0f, -1.0f, 1.0f }, { 1.0f, 0.0f } },
{ { -1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f } },
{ { -1.0f, 1.0f, -1.0f }, { 0.0f, 1.0f } },
{ { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f } },
{ { -1.0f, 1.0f, 1.0f }, { 1.0f, 0.0f } },
{ { -1.0f, 1.0f, -1.0f }, { 1.0f, 1.0f } },
{ { 1.0f, 1.0f, -1.0f }, { 0.0f, 1.0f } },
{ { -1.0f, -1.0f, -1.0f }, { 0.0f, 0.0f } },
{ { 1.0f, -1.0f, -1.0f }, { 1.0f, 0.0f } },
{ { 1.0f, -1.0f, 1.0f }, { 1.0f, 1.0f } },
{ { -1.0f, -1.0f, 1.0f }, { 0.0f, 1.0f } },
};
std::vector<uint32_t> indices = {
0,1,2, 0,2,3, 4,5,6, 4,6,7, 8,9,10, 8,10,11, 12,13,14, 12,14,15, 16,17,18, 16,18,19, 20,21,22, 20,22,23
}; };
// Setup indices
std::vector<uint32_t> indices = { 0,1,2, 2,3,0 };
indexCount = static_cast<uint32_t>(indices.size()); indexCount = static_cast<uint32_t>(indices.size());
// Create buffers // Create buffers
// For the sake of simplicity we won't stage the vertex data to the gpu memory // For the sake of simplicity we won't stage the vertex data to the gpu memory
// Vertex buffer
VK_CHECK_RESULT(vulkanDevice->createBuffer( VK_CHECK_RESULT(vulkanDevice->createBuffer(
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
&vertexBuffer, &vertexBuffer,
vertices.size() * sizeof(Vertex), vertices.size() * sizeof(Vertex),
vertices.data())); vertices.data()));
// Index buffer
VK_CHECK_RESULT(vulkanDevice->createBuffer( VK_CHECK_RESULT(vulkanDevice->createBuffer(
VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
@ -386,97 +401,34 @@ public:
indices.data())); indices.data()));
} }
void setupVertexDescriptions()
{
// Binding description
vertices.bindingDescriptions.resize(1);
vertices.bindingDescriptions[0] =
vks::initializers::vertexInputBindingDescription(
VERTEX_BUFFER_BIND_ID,
sizeof(Vertex),
VK_VERTEX_INPUT_RATE_VERTEX);
// Attribute descriptions
// Describes memory layout and shader positions
vertices.attributeDescriptions.resize(2);
// Location 0 : Position
vertices.attributeDescriptions[0] =
vks::initializers::vertexInputAttributeDescription(
VERTEX_BUFFER_BIND_ID,
0,
VK_FORMAT_R32G32B32_SFLOAT,
0);
// Location 1 : Texture coordinates
vertices.attributeDescriptions[1] =
vks::initializers::vertexInputAttributeDescription(
VERTEX_BUFFER_BIND_ID,
1,
VK_FORMAT_R32G32_SFLOAT,
sizeof(float) * 3);
vertices.inputState = vks::initializers::pipelineVertexInputStateCreateInfo();
vertices.inputState.vertexBindingDescriptionCount = vertices.bindingDescriptions.size();
vertices.inputState.pVertexBindingDescriptions = vertices.bindingDescriptions.data();
vertices.inputState.vertexAttributeDescriptionCount = vertices.attributeDescriptions.size();
vertices.inputState.pVertexAttributeDescriptions = vertices.attributeDescriptions.data();
}
void setupDescriptorPool() void setupDescriptorPool()
{ {
std::vector<VkDescriptorPoolSize> poolSizes = std::vector<VkDescriptorPoolSize> poolSizes = {
{
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1), vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1),
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1) vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1)
}; };
VkDescriptorPoolCreateInfo descriptorPoolInfo = vks::initializers::descriptorPoolCreateInfo(poolSizes.size(), poolSizes.data(), 2);
VkDescriptorPoolCreateInfo descriptorPoolInfo =
vks::initializers::descriptorPoolCreateInfo(
poolSizes.size(),
poolSizes.data(),
2);
VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool)); VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool));
} }
void setupDescriptorSetLayout() void setupDescriptorSetLayout()
{ {
std::vector<VkDescriptorSetLayoutBinding> setLayoutBindings = std::vector<VkDescriptorSetLayoutBinding> setLayoutBindings = {
{
// Binding 0 : Vertex shader uniform buffer // Binding 0 : Vertex shader uniform buffer
vks::initializers::descriptorSetLayoutBinding( vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, 0),
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
VK_SHADER_STAGE_VERTEX_BIT,
0),
// Binding 1 : Fragment shader image sampler (texture array) // Binding 1 : Fragment shader image sampler (texture array)
vks::initializers::descriptorSetLayoutBinding( vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, 1)
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
VK_SHADER_STAGE_FRAGMENT_BIT,
1)
}; };
VkDescriptorSetLayoutCreateInfo descriptorLayout = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings.data(), setLayoutBindings.size());
VkDescriptorSetLayoutCreateInfo descriptorLayout =
vks::initializers::descriptorSetLayoutCreateInfo(
setLayoutBindings.data(),
setLayoutBindings.size());
VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayout)); VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayout));
VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayout, 1);
vks::initializers::pipelineLayoutCreateInfo( VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout));
&descriptorSetLayout,
1);
VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, nullptr, &pipelineLayout));
} }
void setupDescriptorSet() void setupDescriptorSet()
{ {
VkDescriptorSetAllocateInfo allocInfo = VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout, 1);
vks::initializers::descriptorSetAllocateInfo(
descriptorPool,
&descriptorSetLayout,
1);
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet)); VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet));
// Image descriptor for the texture array // Image descriptor for the texture array
@ -486,99 +438,58 @@ public:
textureArray.view, textureArray.view,
textureArray.imageLayout); textureArray.imageLayout);
std::vector<VkWriteDescriptorSet> writeDescriptorSets = std::vector<VkWriteDescriptorSet> writeDescriptorSets = {
{
// Binding 0 : Vertex shader uniform buffer // Binding 0 : Vertex shader uniform buffer
vks::initializers::writeDescriptorSet( vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBufferVS.descriptor),
descriptorSet,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
0,
&uniformBufferVS.descriptor),
// Binding 1 : Fragment shader cubemap sampler // Binding 1 : Fragment shader cubemap sampler
vks::initializers::writeDescriptorSet( vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, &textureDescriptor)
descriptorSet,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
1,
&textureDescriptor)
}; };
vkUpdateDescriptorSets(device, writeDescriptorSets.size(), writeDescriptorSets.data(), 0, NULL); vkUpdateDescriptorSets(device, writeDescriptorSets.size(), writeDescriptorSets.data(), 0, NULL);
} }
void preparePipelines() void preparePipelines()
{ {
VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCI = vks::initializers::pipelineInputAssemblyStateCreateInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE);
vks::initializers::pipelineInputAssemblyStateCreateInfo( VkPipelineRasterizationStateCreateInfo rasterizationStateCI = vks::initializers::pipelineRasterizationStateCreateInfo(VK_POLYGON_MODE_FILL, VK_CULL_MODE_NONE, VK_FRONT_FACE_COUNTER_CLOCKWISE, 0);
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE);
0, VkPipelineColorBlendStateCreateInfo colorBlendStateCI = vks::initializers::pipelineColorBlendStateCreateInfo(1, &blendAttachmentState);
VK_FALSE); VkPipelineDepthStencilStateCreateInfo depthStencilStateCI = vks::initializers::pipelineDepthStencilStateCreateInfo(VK_TRUE, VK_TRUE, VK_COMPARE_OP_LESS_OR_EQUAL);
VkPipelineViewportStateCreateInfo viewportStateCI = vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0);
VkPipelineMultisampleStateCreateInfo multisampleStateCI = vks::initializers::pipelineMultisampleStateCreateInfo(VK_SAMPLE_COUNT_1_BIT, 0);
std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
VkPipelineDynamicStateCreateInfo dynamicStateCI = vks::initializers::pipelineDynamicStateCreateInfo(dynamicStateEnables.data(), dynamicStateEnables.size(), 0);
VkPipelineRasterizationStateCreateInfo rasterizationState = // Vertex bindings and attributes
vks::initializers::pipelineRasterizationStateCreateInfo( VkVertexInputBindingDescription vertexInputBinding = { 0, sizeof(Vertex), VK_VERTEX_INPUT_RATE_VERTEX };
VK_POLYGON_MODE_FILL, std::vector<VkVertexInputAttributeDescription> vertexInputAttributes = {
VK_CULL_MODE_NONE, { 0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(Vertex, pos) },
VK_FRONT_FACE_COUNTER_CLOCKWISE, { 1, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(Vertex, uv) },
0);
VkPipelineColorBlendAttachmentState blendAttachmentState =
vks::initializers::pipelineColorBlendAttachmentState(
0xf,
VK_FALSE);
VkPipelineColorBlendStateCreateInfo colorBlendState =
vks::initializers::pipelineColorBlendStateCreateInfo(
1,
&blendAttachmentState);
VkPipelineDepthStencilStateCreateInfo depthStencilState =
vks::initializers::pipelineDepthStencilStateCreateInfo(
VK_TRUE,
VK_TRUE,
VK_COMPARE_OP_LESS_OR_EQUAL);
VkPipelineViewportStateCreateInfo viewportState =
vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0);
VkPipelineMultisampleStateCreateInfo multisampleState =
vks::initializers::pipelineMultisampleStateCreateInfo(
VK_SAMPLE_COUNT_1_BIT,
0);
std::vector<VkDynamicState> dynamicStateEnables = {
VK_DYNAMIC_STATE_VIEWPORT,
VK_DYNAMIC_STATE_SCISSOR
}; };
VkPipelineDynamicStateCreateInfo dynamicState = VkPipelineVertexInputStateCreateInfo vertexInputStateCI = vks::initializers::pipelineVertexInputStateCreateInfo();
vks::initializers::pipelineDynamicStateCreateInfo( vertexInputStateCI.vertexBindingDescriptionCount = 1;
dynamicStateEnables.data(), vertexInputStateCI.pVertexBindingDescriptions = &vertexInputBinding;
dynamicStateEnables.size(), vertexInputStateCI.vertexAttributeDescriptionCount = static_cast<uint32_t>(vertexInputAttributes.size());
0); vertexInputStateCI.pVertexAttributeDescriptions = vertexInputAttributes.data();
// Instacing pipeline // Instacing pipeline
// Load shaders
std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages; std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages;
shaderStages[0] = loadShader(getAssetPath() + "shaders/texturearray/instancing.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[0] = loadShader(getAssetPath() + "shaders/texturearray/instancing.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
shaderStages[1] = loadShader(getAssetPath() + "shaders/texturearray/instancing.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/texturearray/instancing.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
VkGraphicsPipelineCreateInfo pipelineCreateInfo = VkGraphicsPipelineCreateInfo pipelineCI = vks::initializers::pipelineCreateInfo(pipelineLayout, renderPass, 0);
vks::initializers::pipelineCreateInfo( pipelineCI.pVertexInputState = &vertexInputStateCI;
pipelineLayout, pipelineCI.pInputAssemblyState = &inputAssemblyStateCI;
renderPass, pipelineCI.pRasterizationState = &rasterizationStateCI;
0); pipelineCI.pColorBlendState = &colorBlendStateCI;
pipelineCI.pMultisampleState = &multisampleStateCI;
pipelineCI.pViewportState = &viewportStateCI;
pipelineCI.pDepthStencilState = &depthStencilStateCI;
pipelineCI.pDynamicState = &dynamicStateCI;
pipelineCI.stageCount = shaderStages.size();
pipelineCI.pStages = shaderStages.data();
pipelineCreateInfo.pVertexInputState = &vertices.inputState; VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipeline));
pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState;
pipelineCreateInfo.pRasterizationState = &rasterizationState;
pipelineCreateInfo.pColorBlendState = &colorBlendState;
pipelineCreateInfo.pMultisampleState = &multisampleState;
pipelineCreateInfo.pViewportState = &viewportState;
pipelineCreateInfo.pDepthStencilState = &depthStencilState;
pipelineCreateInfo.pDynamicState = &dynamicState;
pipelineCreateInfo.stageCount = shaderStages.size();
pipelineCreateInfo.pStages = shaderStages.data();
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipeline));
} }
void prepareUniformBuffers() void prepareUniformBuffers()
@ -596,14 +507,13 @@ public:
// Array indices and model matrices are fixed // Array indices and model matrices are fixed
float offset = -1.5f; float offset = -1.5f;
float center = (layerCount*offset) / 2; float center = (layerCount*offset) / 2.0f - (offset * 0.5f);
for (int32_t i = 0; i < layerCount; i++) for (uint32_t i = 0; i < layerCount; i++) {
{
// Instance model matrix // Instance model matrix
uboVS.instance[i].model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, i * offset - center, 0.0f)); uboVS.instance[i].model = glm::translate(glm::mat4(1.0f), glm::vec3(i * offset - center, 0.0f, 0.0f));
uboVS.instance[i].model = glm::rotate(uboVS.instance[i].model, glm::radians(60.0f), glm::vec3(1.0f, 0.0f, 0.0f)); uboVS.instance[i].model = glm::scale(uboVS.instance[i].model, glm::vec3(0.5f));
// Instance texture array index // Instance texture array index
uboVS.instance[i].arrayIndex.x = i; uboVS.instance[i].arrayIndex.x = (float)i;
} }
// Update instanced part of the uniform buffer // Update instanced part of the uniform buffer
@ -617,23 +527,13 @@ public:
// Map persistent // Map persistent
VK_CHECK_RESULT(uniformBufferVS.map()); VK_CHECK_RESULT(uniformBufferVS.map());
updateUniformBufferMatrices(); updateUniformBuffersCamera();
} }
void updateUniformBufferMatrices() void updateUniformBuffersCamera()
{ {
// Only updates the uniform buffer block part containing the global matrices uboVS.matrices.projection = camera.matrices.perspective;
uboVS.matrices.view = camera.matrices.view;
// Projection
uboVS.matrices.projection = glm::perspective(glm::radians(60.0f), (float)width / (float)height, 0.001f, 256.0f);
// View
uboVS.matrices.view = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, -1.0f, zoom));
uboVS.matrices.view = glm::rotate(uboVS.matrices.view, glm::radians(rotation.x), glm::vec3(1.0f, 0.0f, 0.0f));
uboVS.matrices.view = glm::rotate(uboVS.matrices.view, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f));
uboVS.matrices.view = glm::rotate(uboVS.matrices.view, glm::radians(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f));
// Only update the matrices part of the uniform buffer
memcpy(uniformBufferVS.mapped, &uboVS.matrices, sizeof(uboVS.matrices)); memcpy(uniformBufferVS.mapped, &uboVS.matrices, sizeof(uboVS.matrices));
} }
@ -652,8 +552,7 @@ public:
{ {
VulkanExampleBase::prepare(); VulkanExampleBase::prepare();
loadTextures(); loadTextures();
setupVertexDescriptions(); generateCube();
generateQuad();
prepareUniformBuffers(); prepareUniformBuffers();
setupDescriptorSetLayout(); setupDescriptorSetLayout();
preparePipelines(); preparePipelines();
@ -668,12 +567,10 @@ public:
if (!prepared) if (!prepared)
return; return;
draw(); draw();
if (camera.updated)
updateUniformBuffersCamera();
} }
virtual void viewChanged()
{
updateUniformBufferMatrices();
}
}; };
VULKAN_EXAMPLE_MAIN() VULKAN_EXAMPLE_MAIN()