Code cleanup, simplified descriptor setup
This commit is contained in:
parent
53bb3d63f0
commit
668b9c9b57
13 changed files with 102 additions and 195 deletions
|
|
@ -1,6 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* Vulkan Example - Displacement mapping with tessellation shaders
|
* Vulkan Example - Displacement mapping with tessellation shaders
|
||||||
*
|
*
|
||||||
|
* This samples uses tessellation shaders to displace geometry based on a height map
|
||||||
|
*
|
||||||
* Copyright (C) 2016 by Sascha Willems - www.saschawillems.de
|
* Copyright (C) 2016 by 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)
|
||||||
|
|
@ -12,40 +14,32 @@
|
||||||
|
|
||||||
class VulkanExample : public VulkanExampleBase
|
class VulkanExample : public VulkanExampleBase
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
struct {
|
|
||||||
vks::Texture2D colorHeightMap;
|
|
||||||
} textures;
|
|
||||||
public:
|
public:
|
||||||
bool splitScreen = true;
|
bool splitScreen = true;
|
||||||
bool displacement = true;
|
bool displacement = true;
|
||||||
|
|
||||||
vkglTF::Model plane;
|
vkglTF::Model plane;
|
||||||
|
vks::Texture2D colorHeightMap;
|
||||||
|
|
||||||
struct {
|
// Uniform data/buffer used by both tessellation shader stages
|
||||||
vks::Buffer tessControl, tessEval;
|
struct UniformData {
|
||||||
} uniformBuffers;
|
|
||||||
|
|
||||||
struct UBOTessControl {
|
|
||||||
float tessLevel = 64.0f;
|
|
||||||
} uboTessControl;
|
|
||||||
|
|
||||||
struct UBOTessEval {
|
|
||||||
glm::mat4 projection;
|
glm::mat4 projection;
|
||||||
glm::mat4 modelView;
|
glm::mat4 modelView;
|
||||||
glm::vec4 lightPos = glm::vec4(0.0f, -1.0f, 0.0f, 0.0f);
|
glm::vec4 lightPos = glm::vec4(0.0f, -1.0f, 0.0f, 0.0f);
|
||||||
float tessAlpha = 1.0f;
|
float tessAlpha = 1.0f;
|
||||||
float tessStrength = 0.1f;
|
float tessStrength = 0.1f;
|
||||||
} uboTessEval;
|
float tessLevel = 64.0f;
|
||||||
|
} uniformData;
|
||||||
|
vks::Buffer uniformBuffer;
|
||||||
|
|
||||||
struct Pipelines {
|
struct Pipelines {
|
||||||
VkPipeline solid;
|
VkPipeline solid{ VK_NULL_HANDLE };
|
||||||
VkPipeline wireframe = VK_NULL_HANDLE;
|
VkPipeline wireframe{ VK_NULL_HANDLE };
|
||||||
} pipelines;
|
} pipelines;
|
||||||
|
|
||||||
VkPipelineLayout pipelineLayout;
|
VkPipelineLayout pipelineLayout{ VK_NULL_HANDLE };
|
||||||
VkDescriptorSet descriptorSet;
|
VkDescriptorSet descriptorSet{ VK_NULL_HANDLE };
|
||||||
VkDescriptorSetLayout descriptorSetLayout;
|
VkDescriptorSetLayout descriptorSetLayout{ VK_NULL_HANDLE };
|
||||||
|
|
||||||
VulkanExample() : VulkanExampleBase()
|
VulkanExample() : VulkanExampleBase()
|
||||||
{
|
{
|
||||||
|
|
@ -58,19 +52,16 @@ public:
|
||||||
|
|
||||||
~VulkanExample()
|
~VulkanExample()
|
||||||
{
|
{
|
||||||
// Clean up used Vulkan resources
|
if (device) {
|
||||||
// Note : Inherited destructor cleans up resources stored in base class
|
vkDestroyPipeline(device, pipelines.solid, nullptr);
|
||||||
vkDestroyPipeline(device, pipelines.solid, nullptr);
|
if (pipelines.wireframe != VK_NULL_HANDLE) {
|
||||||
if (pipelines.wireframe != VK_NULL_HANDLE) {
|
vkDestroyPipeline(device, pipelines.wireframe, nullptr);
|
||||||
vkDestroyPipeline(device, pipelines.wireframe, nullptr);
|
};
|
||||||
};
|
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
||||||
|
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
|
||||||
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
uniformBuffer.destroy();
|
||||||
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
|
colorHeightMap.destroy();
|
||||||
|
}
|
||||||
uniformBuffers.tessControl.destroy();
|
|
||||||
uniformBuffers.tessEval.destroy();
|
|
||||||
textures.colorHeightMap.destroy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable physical device features required for this example
|
// Enable physical device features required for this example
|
||||||
|
|
@ -96,7 +87,7 @@ public:
|
||||||
{
|
{
|
||||||
const uint32_t glTFLoadingFlags = vkglTF::FileLoadingFlags::PreTransformVertices | vkglTF::FileLoadingFlags::PreMultiplyVertexColors | vkglTF::FileLoadingFlags::FlipY;
|
const uint32_t glTFLoadingFlags = vkglTF::FileLoadingFlags::PreTransformVertices | vkglTF::FileLoadingFlags::PreMultiplyVertexColors | vkglTF::FileLoadingFlags::FlipY;
|
||||||
plane.loadFromFile(getAssetPath() + "models/displacement_plane.gltf", vulkanDevice, queue, glTFLoadingFlags);
|
plane.loadFromFile(getAssetPath() + "models/displacement_plane.gltf", vulkanDevice, queue, glTFLoadingFlags);
|
||||||
textures.colorHeightMap.loadFromFile(getAssetPath() + "textures/stonefloor03_color_height_rgba.ktx", VK_FORMAT_R8G8B8A8_UNORM, vulkanDevice, queue);
|
colorHeightMap.loadFromFile(getAssetPath() + "textures/stonefloor03_color_height_rgba.ktx", VK_FORMAT_R8G8B8A8_UNORM, vulkanDevice, queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void buildCommandBuffers()
|
void buildCommandBuffers()
|
||||||
|
|
@ -156,122 +147,56 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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, 1)
|
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1)
|
||||||
};
|
};
|
||||||
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 : Tessellation shader ubo
|
||||||
{
|
vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, 0),
|
||||||
// Binding 0 : Tessellation control shader ubo
|
// Binding 1 : Combined color (rgb) and height (alpha) map
|
||||||
vks::initializers::descriptorSetLayoutBinding(
|
vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 1),
|
||||||
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
|
||||||
VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
|
|
||||||
0),
|
|
||||||
// Binding 1 : Tessellation evaluation shader ubo
|
|
||||||
vks::initializers::descriptorSetLayoutBinding(
|
|
||||||
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
|
||||||
VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
|
|
||||||
1),
|
|
||||||
// Binding 2 : Combined color (rgb) and height (alpha) map
|
|
||||||
vks::initializers::descriptorSetLayoutBinding(
|
|
||||||
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
||||||
VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
|
|
||||||
2),
|
|
||||||
};
|
};
|
||||||
|
VkDescriptorSetLayoutCreateInfo descriptorLayout = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings);
|
||||||
VkDescriptorSetLayoutCreateInfo descriptorLayout =
|
|
||||||
vks::initializers::descriptorSetLayoutCreateInfo(
|
|
||||||
setLayoutBindings.data(),
|
|
||||||
static_cast<uint32_t>(setLayoutBindings.size()));
|
|
||||||
|
|
||||||
VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayout));
|
VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayout));
|
||||||
|
|
||||||
VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo =
|
// Set
|
||||||
vks::initializers::pipelineLayoutCreateInfo(
|
|
||||||
&descriptorSetLayout,
|
|
||||||
1);
|
|
||||||
|
|
||||||
VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, nullptr, &pipelineLayout));
|
|
||||||
}
|
|
||||||
|
|
||||||
void setupDescriptorSet()
|
|
||||||
{
|
|
||||||
VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout, 1);
|
VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout, 1);
|
||||||
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet));
|
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet));
|
||||||
|
|
||||||
std::vector<VkWriteDescriptorSet> writeDescriptorSets = {
|
std::vector<VkWriteDescriptorSet> writeDescriptorSets = {
|
||||||
// Binding 0 : Tessellation control shader ubo
|
// Binding 0 : Tessellation shader ubo
|
||||||
vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffers.tessControl.descriptor),
|
vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffer.descriptor),
|
||||||
// Binding 1 : Tessellation evaluation shader ubo
|
// Binding 1 : Color and displacement map (alpha channel)
|
||||||
vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, &uniformBuffers.tessEval.descriptor),
|
vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, &colorHeightMap.descriptor),
|
||||||
// Binding 2 : Color and displacement map (alpha channel)
|
|
||||||
vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2, &textures.colorHeightMap.descriptor),
|
|
||||||
};
|
};
|
||||||
vkUpdateDescriptorSets(device, static_cast<uint32_t>(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, NULL);
|
vkUpdateDescriptorSets(device, static_cast<uint32_t>(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void preparePipelines()
|
void preparePipelines()
|
||||||
{
|
{
|
||||||
VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
|
// Layout
|
||||||
vks::initializers::pipelineInputAssemblyStateCreateInfo(
|
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayout, 1);
|
||||||
VK_PRIMITIVE_TOPOLOGY_PATCH_LIST,
|
VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout));
|
||||||
0,
|
|
||||||
VK_FALSE);
|
|
||||||
|
|
||||||
VkPipelineRasterizationStateCreateInfo rasterizationState =
|
// Pipelines
|
||||||
vks::initializers::pipelineRasterizationStateCreateInfo(
|
VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = vks::initializers::pipelineInputAssemblyStateCreateInfo(VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, 0, VK_FALSE);
|
||||||
VK_POLYGON_MODE_FILL,
|
VkPipelineRasterizationStateCreateInfo rasterizationState = vks::initializers::pipelineRasterizationStateCreateInfo(VK_POLYGON_MODE_FILL, VK_CULL_MODE_BACK_BIT, VK_FRONT_FACE_COUNTER_CLOCKWISE, 0);
|
||||||
VK_CULL_MODE_BACK_BIT,
|
VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE);
|
||||||
VK_FRONT_FACE_COUNTER_CLOCKWISE,
|
VkPipelineColorBlendStateCreateInfo colorBlendState = vks::initializers::pipelineColorBlendStateCreateInfo(1, &blendAttachmentState);
|
||||||
0);
|
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, VK_DYNAMIC_STATE_LINE_WIDTH };
|
||||||
|
VkPipelineDynamicStateCreateInfo dynamicState = vks::initializers::pipelineDynamicStateCreateInfo(dynamicStateEnables);
|
||||||
|
VkPipelineTessellationStateCreateInfo tessellationState = vks::initializers::pipelineTessellationStateCreateInfo(3);
|
||||||
|
|
||||||
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,
|
|
||||||
VK_DYNAMIC_STATE_LINE_WIDTH
|
|
||||||
};
|
|
||||||
VkPipelineDynamicStateCreateInfo dynamicState =
|
|
||||||
vks::initializers::pipelineDynamicStateCreateInfo(
|
|
||||||
dynamicStateEnables.data(),
|
|
||||||
static_cast<uint32_t>(dynamicStateEnables.size()),
|
|
||||||
0);
|
|
||||||
|
|
||||||
VkPipelineTessellationStateCreateInfo tessellationState =
|
|
||||||
vks::initializers::pipelineTessellationStateCreateInfo(3);
|
|
||||||
|
|
||||||
// Tessellation pipeline
|
|
||||||
// Load shaders
|
// Load shaders
|
||||||
std::array<VkPipelineShaderStageCreateInfo, 4> shaderStages;
|
std::array<VkPipelineShaderStageCreateInfo, 4> shaderStages;
|
||||||
shaderStages[0] = loadShader(getShadersPath() + "displacement/base.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
|
shaderStages[0] = loadShader(getShadersPath() + "displacement/base.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
|
||||||
|
|
@ -292,6 +217,7 @@ public:
|
||||||
pipelineCI.pStages = shaderStages.data();
|
pipelineCI.pStages = shaderStages.data();
|
||||||
pipelineCI.pVertexInputState = vkglTF::Vertex::getPipelineVertexInputState({ vkglTF::VertexComponent::Position, vkglTF::VertexComponent::Normal, vkglTF::VertexComponent::UV });
|
pipelineCI.pVertexInputState = vkglTF::Vertex::getPipelineVertexInputState({ vkglTF::VertexComponent::Position, vkglTF::VertexComponent::Normal, vkglTF::VertexComponent::UV });
|
||||||
|
|
||||||
|
// Tessellation pipelines
|
||||||
// Solid pipeline
|
// Solid pipeline
|
||||||
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.solid));
|
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.solid));
|
||||||
if (deviceFeatures.fillModeNonSolid) {
|
if (deviceFeatures.fillModeNonSolid) {
|
||||||
|
|
@ -306,88 +232,54 @@ public:
|
||||||
void prepareUniformBuffers()
|
void prepareUniformBuffers()
|
||||||
{
|
{
|
||||||
// Tessellation evaluation shader uniform buffer
|
// Tessellation evaluation shader uniform buffer
|
||||||
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, &uniformBuffer, sizeof(UniformData)));
|
||||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
|
||||||
&uniformBuffers.tessEval,
|
|
||||||
sizeof(uboTessEval)));
|
|
||||||
|
|
||||||
// Tessellation control shader uniform buffer
|
|
||||||
VK_CHECK_RESULT(vulkanDevice->createBuffer(
|
|
||||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
|
||||||
&uniformBuffers.tessControl,
|
|
||||||
sizeof(uboTessControl)));
|
|
||||||
|
|
||||||
// Map persistent
|
// Map persistent
|
||||||
VK_CHECK_RESULT(uniformBuffers.tessControl.map());
|
VK_CHECK_RESULT(uniformBuffer.map());
|
||||||
VK_CHECK_RESULT(uniformBuffers.tessEval.map());
|
|
||||||
|
|
||||||
updateUniformBuffers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateUniformBuffers()
|
void updateUniformBuffers()
|
||||||
{
|
{
|
||||||
uboTessEval.projection = camera.matrices.perspective;
|
uniformData.projection = camera.matrices.perspective;
|
||||||
uboTessEval.modelView = camera.matrices.view;
|
uniformData.modelView = camera.matrices.view;
|
||||||
uboTessEval.lightPos.y = -0.5f - uboTessEval.tessStrength;
|
uniformData.lightPos.y = -0.5f - uniformData.tessStrength;
|
||||||
memcpy(uniformBuffers.tessEval.mapped, &uboTessEval, sizeof(uboTessEval));
|
|
||||||
|
|
||||||
// Tessellation control
|
// Tessellation control
|
||||||
float savedLevel = uboTessControl.tessLevel;
|
float savedLevel = uniformData.tessLevel;
|
||||||
if (!displacement)
|
// If displacement is unchecked, we simply set the tessellation level to 1.0f, which disables tessellation
|
||||||
{
|
if (!displacement) {
|
||||||
uboTessControl.tessLevel = 1.0f;
|
uniformData.tessLevel = 1.0f;
|
||||||
}
|
}
|
||||||
|
memcpy(uniformBuffer.mapped, &uniformData, sizeof(UniformData));
|
||||||
memcpy(uniformBuffers.tessControl.mapped, &uboTessControl, sizeof(uboTessControl));
|
if (!displacement) {
|
||||||
|
uniformData.tessLevel = savedLevel;
|
||||||
if (!displacement)
|
|
||||||
{
|
|
||||||
uboTessControl.tessLevel = savedLevel;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw()
|
|
||||||
{
|
|
||||||
VulkanExampleBase::prepareFrame();
|
|
||||||
|
|
||||||
// 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()
|
||||||
{
|
{
|
||||||
VulkanExampleBase::prepare();
|
VulkanExampleBase::prepare();
|
||||||
loadAssets();
|
loadAssets();
|
||||||
prepareUniformBuffers();
|
prepareUniformBuffers();
|
||||||
setupDescriptorSetLayout();
|
setupDescriptors();
|
||||||
preparePipelines();
|
preparePipelines();
|
||||||
setupDescriptorPool();
|
|
||||||
setupDescriptorSet();
|
|
||||||
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();
|
|
||||||
if (camera.updated) {
|
|
||||||
updateUniformBuffers();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void viewChanged()
|
|
||||||
{
|
|
||||||
updateUniformBuffers();
|
updateUniformBuffers();
|
||||||
|
draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
|
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
|
||||||
|
|
@ -396,10 +288,10 @@ public:
|
||||||
if (overlay->checkBox("Tessellation displacement", &displacement)) {
|
if (overlay->checkBox("Tessellation displacement", &displacement)) {
|
||||||
updateUniformBuffers();
|
updateUniformBuffers();
|
||||||
}
|
}
|
||||||
if (overlay->inputFloat("Strength", &uboTessEval.tessStrength, 0.025f, 3)) {
|
if (overlay->inputFloat("Strength", &uniformData.tessStrength, 0.025f, 3)) {
|
||||||
updateUniformBuffers();
|
updateUniformBuffers();
|
||||||
}
|
}
|
||||||
if (overlay->inputFloat("Level", &uboTessControl.tessLevel, 0.5f, 2)) {
|
if (overlay->inputFloat("Level", &uniformData.tessLevel, 0.5f, 2)) {
|
||||||
updateUniformBuffers();
|
updateUniformBuffers();
|
||||||
}
|
}
|
||||||
if (deviceFeatures.fillModeNonSolid) {
|
if (deviceFeatures.fillModeNonSolid) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
layout (binding = 2) uniform sampler2D colorMap;
|
layout (binding = 1) uniform sampler2D colorMap;
|
||||||
|
|
||||||
layout (location = 0) in vec3 inNormal;
|
layout (location = 0) in vec3 inNormal;
|
||||||
layout (location = 1) in vec2 inUV;
|
layout (location = 1) in vec2 inUV;
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -2,6 +2,11 @@
|
||||||
|
|
||||||
layout (binding = 0) uniform UBO
|
layout (binding = 0) uniform UBO
|
||||||
{
|
{
|
||||||
|
mat4 projection;
|
||||||
|
mat4 modelview;
|
||||||
|
vec4 lightPos;
|
||||||
|
float tessAlpha;
|
||||||
|
float tessStrength;
|
||||||
float tessLevel;
|
float tessLevel;
|
||||||
} ubo;
|
} ubo;
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -1,15 +1,16 @@
|
||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
layout (binding = 1) uniform UBO
|
layout (binding = 0) uniform UBO
|
||||||
{
|
{
|
||||||
mat4 projection;
|
mat4 projection;
|
||||||
mat4 modelview;
|
mat4 modelview;
|
||||||
vec4 lightPos;
|
vec4 lightPos;
|
||||||
float tessAlpha;
|
float tessAlpha;
|
||||||
float tessStrength;
|
float tessStrength;
|
||||||
|
float tessLevel;
|
||||||
} ubo;
|
} ubo;
|
||||||
|
|
||||||
layout (binding = 2) uniform sampler2D displacementMap;
|
layout (binding = 1) uniform sampler2D displacementMap;
|
||||||
|
|
||||||
layout(triangles, equal_spacing, cw) in;
|
layout(triangles, equal_spacing, cw) in;
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -1,7 +1,8 @@
|
||||||
// Copyright 2020 Google LLC
|
// Copyright 2020 Google LLC
|
||||||
|
// Copyright 2023 Sascha Willems
|
||||||
|
|
||||||
Texture2D textureColorMap : register(t2);
|
Texture2D textureColorMap : register(t1);
|
||||||
SamplerState samplerColorMap : register(s2);
|
SamplerState samplerColorMap : register(s1);
|
||||||
|
|
||||||
struct DSOutput
|
struct DSOutput
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -1,7 +1,13 @@
|
||||||
// Copyright 2020 Google LLC
|
// Copyright 2020 Google LLC
|
||||||
|
// Copyright 2023 Sascha Willems
|
||||||
|
|
||||||
struct UBO
|
struct UBO
|
||||||
{
|
{
|
||||||
|
float4x4 projection;
|
||||||
|
float4x4 model;
|
||||||
|
float4 lightPos;
|
||||||
|
float tessAlpha;
|
||||||
|
float tessStrength;
|
||||||
float tessLevel;
|
float tessLevel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright 2020 Google LLC
|
// Copyright 2020 Google LLC
|
||||||
|
// Copyright 2023 Sascha Willems
|
||||||
|
|
||||||
struct UBO
|
struct UBO
|
||||||
{
|
{
|
||||||
|
|
@ -7,12 +8,13 @@ struct UBO
|
||||||
float4 lightPos;
|
float4 lightPos;
|
||||||
float tessAlpha;
|
float tessAlpha;
|
||||||
float tessStrength;
|
float tessStrength;
|
||||||
|
float tessLevel;
|
||||||
};
|
};
|
||||||
|
|
||||||
cbuffer ubo : register(b1) { UBO ubo; }
|
cbuffer ubo : register(b0) { UBO ubo; }
|
||||||
|
|
||||||
Texture2D textureDisplacementMap : register(t2);
|
Texture2D textureDisplacementMap : register(t1);
|
||||||
SamplerState samplerDisplacementMap : register(s2);
|
SamplerState samplerDisplacementMap : register(s1);
|
||||||
|
|
||||||
struct HSOutput
|
struct HSOutput
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue