Code cleanup, code comments
This commit is contained in:
parent
9023421b0e
commit
0888d1c9b0
2 changed files with 92 additions and 131 deletions
|
|
@ -1,5 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Vulkan Example - CPU based particle system
|
* Vulkan Example - CPU based particle system
|
||||||
|
*
|
||||||
|
* This sample renders a particle system that is updated on the host (by the CPU) and rendered by the GPU using a vertex buffer
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016-2023 by Sascha Willems - www.saschawillems.de
|
* Copyright (C) 2016-2023 by Sascha Willems - www.saschawillems.de
|
||||||
*
|
*
|
||||||
|
|
@ -10,10 +12,11 @@
|
||||||
#include "VulkanglTFModel.h"
|
#include "VulkanglTFModel.h"
|
||||||
|
|
||||||
#define PARTICLE_COUNT 512
|
#define PARTICLE_COUNT 512
|
||||||
#define PARTICLE_SIZE 10.0f
|
|
||||||
|
|
||||||
#define FLAME_RADIUS 8.0f
|
#define FLAME_RADIUS 8.0f
|
||||||
|
|
||||||
|
// The particle system is made from two different particle types
|
||||||
|
// That type defines how a particle is rendered
|
||||||
#define PARTICLE_TYPE_FLAME 0
|
#define PARTICLE_TYPE_FLAME 0
|
||||||
#define PARTICLE_TYPE_SMOKE 1
|
#define PARTICLE_TYPE_SMOKE 1
|
||||||
|
|
||||||
|
|
@ -24,7 +27,6 @@ struct Particle {
|
||||||
float size;
|
float size;
|
||||||
float rotation;
|
float rotation;
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
// Attributes not used in shader
|
|
||||||
glm::vec4 vel;
|
glm::vec4 vel;
|
||||||
float rotationSpeed;
|
float rotationSpeed;
|
||||||
};
|
};
|
||||||
|
|
@ -43,56 +45,60 @@ public:
|
||||||
vks::Texture2D colorMap;
|
vks::Texture2D colorMap;
|
||||||
vks::Texture2D normalMap;
|
vks::Texture2D normalMap;
|
||||||
} floor;
|
} floor;
|
||||||
} textures;
|
} textures{};
|
||||||
|
|
||||||
vkglTF::Model environment;
|
vkglTF::Model environment;
|
||||||
|
|
||||||
|
// These parameters define the particle system behaviour
|
||||||
glm::vec3 emitterPos = glm::vec3(0.0f, -FLAME_RADIUS + 2.0f, 0.0f);
|
glm::vec3 emitterPos = glm::vec3(0.0f, -FLAME_RADIUS + 2.0f, 0.0f);
|
||||||
glm::vec3 minVel = glm::vec3(-3.0f, 0.5f, -3.0f);
|
glm::vec3 minVel = glm::vec3(-3.0f, 0.5f, -3.0f);
|
||||||
glm::vec3 maxVel = glm::vec3(3.0f, 7.0f, 3.0f);
|
glm::vec3 maxVel = glm::vec3(3.0f, 7.0f, 3.0f);
|
||||||
|
|
||||||
struct {
|
struct Particles {
|
||||||
VkBuffer buffer;
|
VkBuffer buffer{ VK_NULL_HANDLE };
|
||||||
VkDeviceMemory memory;
|
VkDeviceMemory memory{ VK_NULL_HANDLE };
|
||||||
// Store the mapped address of the particle data for reuse
|
// Store the mapped address of the particle data for reuse
|
||||||
void *mappedMemory;
|
void *mappedMemory;
|
||||||
// Size of the particle buffer in bytes
|
// Size of the particle buffer in bytes
|
||||||
size_t size;
|
size_t size{ 0 };
|
||||||
} particles;
|
} particles;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
vks::Buffer fire;
|
vks::Buffer particles;
|
||||||
vks::Buffer environment;
|
vks::Buffer environment;
|
||||||
} uniformBuffers;
|
} uniformBuffers;
|
||||||
|
|
||||||
struct UBOVS {
|
struct UniformDataParticles {
|
||||||
glm::mat4 projection;
|
glm::mat4 projection;
|
||||||
glm::mat4 modelView;
|
glm::mat4 modelView;
|
||||||
|
// The viewport dimension is used by the particle system vertex shader
|
||||||
|
// to calculate the absolute point size based on the current viewport size
|
||||||
glm::vec2 viewportDim;
|
glm::vec2 viewportDim;
|
||||||
float pointSize = PARTICLE_SIZE;
|
// This is the base point size for all particles
|
||||||
} uboVS;
|
float pointSize{ 10.0f };
|
||||||
|
} uniformDataParticles;
|
||||||
|
|
||||||
struct UBOEnv {
|
struct UniformDataEnvironment {
|
||||||
glm::mat4 projection;
|
glm::mat4 projection;
|
||||||
glm::mat4 modelView;
|
glm::mat4 modelView;
|
||||||
glm::mat4 normal;
|
glm::mat4 normal;
|
||||||
glm::vec4 lightPos = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f);
|
glm::vec4 lightPos = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
} uboEnv;
|
} uniformDataEnvironment;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
VkPipeline particles;
|
VkPipeline particles{ VK_NULL_HANDLE };
|
||||||
VkPipeline environment;
|
VkPipeline environment{ VK_NULL_HANDLE };
|
||||||
} pipelines;
|
} pipelines;
|
||||||
|
|
||||||
VkPipelineLayout pipelineLayout;
|
VkPipelineLayout pipelineLayout{ VK_NULL_HANDLE };
|
||||||
VkDescriptorSetLayout descriptorSetLayout;
|
VkDescriptorSetLayout descriptorSetLayout{ VK_NULL_HANDLE };
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
VkDescriptorSet particles;
|
VkDescriptorSet particles{ VK_NULL_HANDLE };
|
||||||
VkDescriptorSet environment;
|
VkDescriptorSet environment{ VK_NULL_HANDLE };
|
||||||
} descriptorSets;
|
} descriptorSets;
|
||||||
|
|
||||||
std::vector<Particle> particleBuffer;
|
std::vector<Particle> particleBuffer{};
|
||||||
|
|
||||||
std::default_random_engine rndEngine;
|
std::default_random_engine rndEngine;
|
||||||
|
|
||||||
|
|
@ -109,28 +115,27 @@ public:
|
||||||
|
|
||||||
~VulkanExample()
|
~VulkanExample()
|
||||||
{
|
{
|
||||||
// Clean up used Vulkan resources
|
if (device) {
|
||||||
// Note : Inherited destructor cleans up resources stored in base class
|
textures.particles.smoke.destroy();
|
||||||
|
textures.particles.fire.destroy();
|
||||||
|
textures.floor.colorMap.destroy();
|
||||||
|
textures.floor.normalMap.destroy();
|
||||||
|
|
||||||
textures.particles.smoke.destroy();
|
vkDestroyPipeline(device, pipelines.particles, nullptr);
|
||||||
textures.particles.fire.destroy();
|
vkDestroyPipeline(device, pipelines.environment, nullptr);
|
||||||
textures.floor.colorMap.destroy();
|
|
||||||
textures.floor.normalMap.destroy();
|
|
||||||
|
|
||||||
vkDestroyPipeline(device, pipelines.particles, nullptr);
|
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
||||||
vkDestroyPipeline(device, pipelines.environment, nullptr);
|
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
|
||||||
|
|
||||||
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
vkUnmapMemory(device, particles.memory);
|
||||||
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
|
vkDestroyBuffer(device, particles.buffer, nullptr);
|
||||||
|
vkFreeMemory(device, particles.memory, nullptr);
|
||||||
|
|
||||||
vkUnmapMemory(device, particles.memory);
|
uniformBuffers.environment.destroy();
|
||||||
vkDestroyBuffer(device, particles.buffer, nullptr);
|
uniformBuffers.particles.destroy();
|
||||||
vkFreeMemory(device, particles.memory, nullptr);
|
|
||||||
|
|
||||||
uniformBuffers.environment.destroy();
|
vkDestroySampler(device, textures.particles.sampler, nullptr);
|
||||||
uniformBuffers.fire.destroy();
|
}
|
||||||
|
|
||||||
vkDestroySampler(device, textures.particles.sampler, nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void getEnabledFeatures()
|
virtual void getEnabledFeatures()
|
||||||
|
|
@ -184,7 +189,7 @@ public:
|
||||||
vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSets.particles, 0, nullptr);
|
vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSets.particles, 0, nullptr);
|
||||||
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.particles);
|
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.particles);
|
||||||
vkCmdBindVertexBuffers(drawCmdBuffers[i], 0, 1, &particles.buffer, offsets);
|
vkCmdBindVertexBuffers(drawCmdBuffers[i], 0, 1, &particles.buffer, offsets);
|
||||||
vkCmdDraw(drawCmdBuffers[i], PARTICLE_COUNT, 1, 0, 0);
|
vkCmdDraw(drawCmdBuffers[i], static_cast<uint32_t>(particles.size), 1, 0, 0);
|
||||||
|
|
||||||
drawUI(drawCmdBuffers[i]);
|
drawUI(drawCmdBuffers[i]);
|
||||||
|
|
||||||
|
|
@ -222,6 +227,7 @@ public:
|
||||||
particle->pos += glm::vec4(emitterPos, 0.0f);
|
particle->pos += glm::vec4(emitterPos, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Change the type of a particle, e.g. from flame to smoke
|
||||||
void transitionParticle(Particle *particle)
|
void transitionParticle(Particle *particle)
|
||||||
{
|
{
|
||||||
switch (particle->type)
|
switch (particle->type)
|
||||||
|
|
@ -251,6 +257,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize the particle system and create a vertex buffer for rendering the particles
|
||||||
void prepareParticles()
|
void prepareParticles()
|
||||||
{
|
{
|
||||||
particleBuffer.resize(PARTICLE_COUNT);
|
particleBuffer.resize(PARTICLE_COUNT);
|
||||||
|
|
@ -274,6 +281,7 @@ public:
|
||||||
VK_CHECK_RESULT(vkMapMemory(device, particles.memory, 0, particles.size, 0, &particles.mappedMemory));
|
VK_CHECK_RESULT(vkMapMemory(device, particles.memory, 0, particles.size, 0, &particles.mappedMemory));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the state of all particles
|
||||||
void updateParticles()
|
void updateParticles()
|
||||||
{
|
{
|
||||||
float particleTimer = frameTimer * 0.45f;
|
float particleTimer = frameTimer * 0.45f;
|
||||||
|
|
@ -294,12 +302,14 @@ public:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
particle.rotation += particleTimer * particle.rotationSpeed;
|
particle.rotation += particleTimer * particle.rotationSpeed;
|
||||||
// Transition particle state
|
// If a particle has faded out, turn it into the other type (e.g. flame to smoke and vice versa)
|
||||||
if (particle.alpha > 2.0f)
|
if (particle.alpha > 2.0f)
|
||||||
{
|
{
|
||||||
transitionParticle(&particle);
|
transitionParticle(&particle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy the updated particles to the vertex buffer
|
||||||
size_t size = particleBuffer.size() * sizeof(Particle);
|
size_t size = particleBuffer.size() * sizeof(Particle);
|
||||||
memcpy(particles.mappedMemory, particleBuffer.data(), size);
|
memcpy(particles.mappedMemory, particleBuffer.data(), size);
|
||||||
}
|
}
|
||||||
|
|
@ -345,18 +355,17 @@ public:
|
||||||
environment.loadFromFile(getAssetPath() + "models/fireplace.gltf", vulkanDevice, queue, glTFLoadingFlags);
|
environment.loadFromFile(getAssetPath() + "models/fireplace.gltf", vulkanDevice, queue, glTFLoadingFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupDescriptorPool()
|
void setupDescriptors()
|
||||||
{
|
{
|
||||||
|
// Pool
|
||||||
std::vector<VkDescriptorPoolSize> poolSizes = {
|
std::vector<VkDescriptorPoolSize> poolSizes = {
|
||||||
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2),
|
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2),
|
||||||
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 4)
|
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 4)
|
||||||
};
|
};
|
||||||
VkDescriptorPoolCreateInfo descriptorPoolInfo = vks::initializers::descriptorPoolCreateInfo(poolSizes, 2);
|
VkDescriptorPoolCreateInfo descriptorPoolInfo = vks::initializers::descriptorPoolCreateInfo(poolSizes, 2);
|
||||||
VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool));
|
VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool));
|
||||||
}
|
|
||||||
|
|
||||||
void setupDescriptorSetLayout()
|
// Layout
|
||||||
{
|
|
||||||
std::vector<VkDescriptorSetLayoutBinding> setLayoutBindings = {
|
std::vector<VkDescriptorSetLayoutBinding> setLayoutBindings = {
|
||||||
// Binding 0 : Vertex shader uniform buffer
|
// Binding 0 : Vertex shader uniform buffer
|
||||||
vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, 0),
|
vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, 0),
|
||||||
|
|
@ -365,16 +374,10 @@ public:
|
||||||
// Binding 1 : Fragment shader image sampler
|
// Binding 1 : Fragment shader image sampler
|
||||||
vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT,2)
|
vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT,2)
|
||||||
};
|
};
|
||||||
|
|
||||||
VkDescriptorSetLayoutCreateInfo descriptorLayout = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings);
|
VkDescriptorSetLayoutCreateInfo descriptorLayout = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings);
|
||||||
VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayout));
|
VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayout));
|
||||||
|
|
||||||
VkPipelineLayoutCreateInfo pipelineLayoutCI = vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayout, 1);
|
// Sets
|
||||||
VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCI, nullptr, &pipelineLayout));
|
|
||||||
}
|
|
||||||
|
|
||||||
void setupDescriptorSets()
|
|
||||||
{
|
|
||||||
std::vector<VkWriteDescriptorSet> writeDescriptorSets;
|
std::vector<VkWriteDescriptorSet> writeDescriptorSets;
|
||||||
|
|
||||||
VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout, 1);
|
VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout, 1);
|
||||||
|
|
@ -382,20 +385,12 @@ public:
|
||||||
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSets.particles));
|
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSets.particles));
|
||||||
|
|
||||||
// Image descriptor for the color map texture
|
// Image descriptor for the color map texture
|
||||||
VkDescriptorImageInfo texDescriptorSmoke =
|
VkDescriptorImageInfo texDescriptorSmoke = vks::initializers::descriptorImageInfo(textures.particles.sampler, textures.particles.smoke.view, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
vks::initializers::descriptorImageInfo(
|
VkDescriptorImageInfo texDescriptorFire = vks::initializers::descriptorImageInfo(textures.particles.sampler, textures.particles.fire.view, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
textures.particles.sampler,
|
|
||||||
textures.particles.smoke.view,
|
|
||||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
|
||||||
VkDescriptorImageInfo texDescriptorFire =
|
|
||||||
vks::initializers::descriptorImageInfo(
|
|
||||||
textures.particles.sampler,
|
|
||||||
textures.particles.fire.view,
|
|
||||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
|
||||||
|
|
||||||
writeDescriptorSets = {
|
writeDescriptorSets = {
|
||||||
// Binding 0: Vertex shader uniform buffer
|
// Binding 0: Vertex shader uniform buffer
|
||||||
vks::initializers::writeDescriptorSet(descriptorSets.particles, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffers.fire.descriptor),
|
vks::initializers::writeDescriptorSet(descriptorSets.particles, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffers.particles.descriptor),
|
||||||
// Binding 1: Smoke texture
|
// Binding 1: Smoke texture
|
||||||
vks::initializers::writeDescriptorSet(descriptorSets.particles, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, &texDescriptorSmoke),
|
vks::initializers::writeDescriptorSet(descriptorSets.particles, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, &texDescriptorSmoke),
|
||||||
// Binding 1: Fire texture array
|
// Binding 1: Fire texture array
|
||||||
|
|
@ -405,7 +400,6 @@ public:
|
||||||
|
|
||||||
// Environment
|
// Environment
|
||||||
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSets.environment));
|
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSets.environment));
|
||||||
|
|
||||||
writeDescriptorSets = {
|
writeDescriptorSets = {
|
||||||
// Binding 0: Vertex shader uniform buffer
|
// Binding 0: Vertex shader uniform buffer
|
||||||
vks::initializers::writeDescriptorSet(descriptorSets.environment, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffers.environment.descriptor),
|
vks::initializers::writeDescriptorSet(descriptorSets.environment, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffers.environment.descriptor),
|
||||||
|
|
@ -419,6 +413,11 @@ public:
|
||||||
|
|
||||||
void preparePipelines()
|
void preparePipelines()
|
||||||
{
|
{
|
||||||
|
// Layout
|
||||||
|
VkPipelineLayoutCreateInfo pipelineLayoutCI = vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayout, 1);
|
||||||
|
VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCI, nullptr, &pipelineLayout));
|
||||||
|
|
||||||
|
// Pipelines
|
||||||
VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = vks::initializers::pipelineInputAssemblyStateCreateInfo(VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0, VK_FALSE);
|
VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = vks::initializers::pipelineInputAssemblyStateCreateInfo(VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0, VK_FALSE);
|
||||||
VkPipelineRasterizationStateCreateInfo rasterizationState = vks::initializers::pipelineRasterizationStateCreateInfo(VK_POLYGON_MODE_FILL, VK_CULL_MODE_BACK_BIT, VK_FRONT_FACE_COUNTER_CLOCKWISE, 0);
|
VkPipelineRasterizationStateCreateInfo rasterizationState = vks::initializers::pipelineRasterizationStateCreateInfo(VK_POLYGON_MODE_FILL, VK_CULL_MODE_BACK_BIT, VK_FRONT_FACE_COUNTER_CLOCKWISE, 0);
|
||||||
VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE);
|
VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE);
|
||||||
|
|
@ -501,62 +500,33 @@ public:
|
||||||
void prepareUniformBuffers()
|
void prepareUniformBuffers()
|
||||||
{
|
{
|
||||||
// Vertex shader uniform buffer block
|
// Vertex shader uniform buffer block
|
||||||
VK_CHECK_RESULT(vulkanDevice->createBuffer(
|
VK_CHECK_RESULT(vulkanDevice->createBuffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &uniformBuffers.particles, sizeof(UniformDataParticles)));
|
||||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
|
||||||
&uniformBuffers.fire,
|
|
||||||
sizeof(uboVS)));
|
|
||||||
|
|
||||||
// Vertex shader uniform buffer block
|
// Vertex shader uniform buffer block
|
||||||
VK_CHECK_RESULT(vulkanDevice->createBuffer(
|
VK_CHECK_RESULT(vulkanDevice->createBuffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &uniformBuffers.environment, sizeof(UniformDataEnvironment)));
|
||||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
|
||||||
&uniformBuffers.environment,
|
|
||||||
sizeof(uboEnv)));
|
|
||||||
|
|
||||||
// Map persistent
|
// Map persistent
|
||||||
VK_CHECK_RESULT(uniformBuffers.fire.map());
|
VK_CHECK_RESULT(uniformBuffers.particles.map());
|
||||||
VK_CHECK_RESULT(uniformBuffers.environment.map());
|
VK_CHECK_RESULT(uniformBuffers.environment.map());
|
||||||
|
|
||||||
updateUniformBuffers();
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateUniformBufferLight()
|
|
||||||
{
|
|
||||||
// Environment
|
|
||||||
uboEnv.lightPos.x = sin(timer * 2.0f * float(M_PI)) * 1.5f;
|
|
||||||
uboEnv.lightPos.y = 0.0f;
|
|
||||||
uboEnv.lightPos.z = cos(timer * 2.0f * float(M_PI)) * 1.5f;
|
|
||||||
memcpy(uniformBuffers.environment.mapped, &uboEnv, sizeof(uboEnv));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateUniformBuffers()
|
void updateUniformBuffers()
|
||||||
{
|
{
|
||||||
// Particle system fire
|
// Particle system fire
|
||||||
uboVS.projection = camera.matrices.perspective;
|
uniformDataParticles.projection = camera.matrices.perspective;
|
||||||
uboVS.modelView = camera.matrices.view;
|
uniformDataParticles.modelView = camera.matrices.view;
|
||||||
uboVS.viewportDim = glm::vec2((float)width, (float)height);
|
uniformDataParticles.viewportDim = glm::vec2((float)width, (float)height);
|
||||||
memcpy(uniformBuffers.fire.mapped, &uboVS, sizeof(uboVS));
|
memcpy(uniformBuffers.particles.mapped, &uniformDataParticles, sizeof(UniformDataParticles));
|
||||||
|
|
||||||
// Environment
|
// Environment
|
||||||
uboEnv.projection = camera.matrices.perspective;
|
uniformDataEnvironment.projection = camera.matrices.perspective;
|
||||||
uboEnv.modelView = camera.matrices.view;
|
uniformDataEnvironment.modelView = camera.matrices.view;
|
||||||
uboEnv.normal = glm::inverseTranspose(uboEnv.modelView);
|
uniformDataEnvironment.normal = glm::inverseTranspose(uniformDataEnvironment.modelView);
|
||||||
memcpy(uniformBuffers.environment.mapped, &uboEnv, sizeof(uboEnv));
|
// Update light position
|
||||||
}
|
if (!paused) {
|
||||||
|
uniformDataEnvironment.lightPos.x = sin(timer * 2.0f * float(M_PI)) * 1.5f;
|
||||||
void draw()
|
uniformDataEnvironment.lightPos.y = 0.0f;
|
||||||
{
|
uniformDataEnvironment.lightPos.z = cos(timer * 2.0f * float(M_PI)) * 1.5f;
|
||||||
VulkanExampleBase::prepareFrame();
|
}
|
||||||
|
memcpy(uniformBuffers.environment.mapped, &uniformDataEnvironment, sizeof(UniformDataEnvironment));
|
||||||
// Command buffer to be submitted to the queue
|
|
||||||
submitInfo.commandBufferCount = 1;
|
|
||||||
submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer];
|
|
||||||
|
|
||||||
// Submit to queue
|
|
||||||
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
|
|
||||||
|
|
||||||
VulkanExampleBase::submitFrame();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepare()
|
void prepare()
|
||||||
|
|
@ -565,33 +535,30 @@ public:
|
||||||
loadAssets();
|
loadAssets();
|
||||||
prepareParticles();
|
prepareParticles();
|
||||||
prepareUniformBuffers();
|
prepareUniformBuffers();
|
||||||
setupDescriptorSetLayout();
|
setupDescriptors();
|
||||||
preparePipelines();
|
preparePipelines();
|
||||||
setupDescriptorPool();
|
|
||||||
setupDescriptorSets();
|
|
||||||
buildCommandBuffers();
|
buildCommandBuffers();
|
||||||
prepared = true;
|
prepared = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void draw()
|
||||||
|
{
|
||||||
|
VulkanExampleBase::prepareFrame();
|
||||||
|
submitInfo.commandBufferCount = 1;
|
||||||
|
submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer];
|
||||||
|
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
|
||||||
|
VulkanExampleBase::submitFrame();
|
||||||
|
}
|
||||||
|
|
||||||
virtual void render()
|
virtual void render()
|
||||||
{
|
{
|
||||||
if (!prepared)
|
if (!prepared)
|
||||||
return;
|
return;
|
||||||
draw();
|
updateUniformBuffers();
|
||||||
if (!paused)
|
if (!paused) {
|
||||||
{
|
|
||||||
updateUniformBufferLight();
|
|
||||||
updateParticles();
|
updateParticles();
|
||||||
}
|
}
|
||||||
if (camera.updated)
|
draw();
|
||||||
{
|
|
||||||
updateUniformBuffers();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void viewChanged()
|
|
||||||
{
|
|
||||||
updateUniformBuffers();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,6 @@ layout (binding = 0) uniform UBO
|
||||||
float pointSize;
|
float pointSize;
|
||||||
} ubo;
|
} ubo;
|
||||||
|
|
||||||
out gl_PerVertex
|
|
||||||
{
|
|
||||||
vec4 gl_Position;
|
|
||||||
float gl_PointSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
void main ()
|
void main ()
|
||||||
{
|
{
|
||||||
outColor = inColor;
|
outColor = inColor;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue