depth buffering
This commit is contained in:
parent
f541f6ec8c
commit
02cd99a73a
292
src/main.cpp
292
src/main.cpp
|
@ -1,11 +1,13 @@
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <glm/glm.hpp>
|
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#include <stb_image.h>
|
#include <stb_image.h>
|
||||||
|
|
||||||
|
@ -42,7 +44,7 @@ constexpr bool enableValidationLayers = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
glm::vec2 pos;
|
glm::vec3 pos;
|
||||||
glm::vec3 color;
|
glm::vec3 color;
|
||||||
glm::vec2 tex_coord;
|
glm::vec2 tex_coord;
|
||||||
|
|
||||||
|
@ -52,21 +54,30 @@ struct Vertex {
|
||||||
|
|
||||||
static fn getAttributeDescriptions() -> std::array<vk::VertexInputAttributeDescription, 3> {
|
static fn getAttributeDescriptions() -> std::array<vk::VertexInputAttributeDescription, 3> {
|
||||||
return {
|
return {
|
||||||
{ { 0, 0, vk::Format::eR32G32Sfloat, offsetof(Vertex, pos) },
|
{ { 0, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, pos) },
|
||||||
{ 1, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, color) },
|
{ 1, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, color) },
|
||||||
{ 2, 0, vk::Format::eR32G32Sfloat, offsetof(Vertex, tex_coord) } }
|
{ 2, 0, vk::Format::eR32G32Sfloat, offsetof(Vertex, tex_coord) } }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr std::array<Vertex, 4> vertices = {
|
constexpr std::array<Vertex, 8> vertices = {
|
||||||
{ { { -0.5F, -0.5F }, { 1.0F, 0.0F, 0.0F }, { 1.0F, 0.0F } },
|
{ { { -0.5F, -0.5F, 0.0F }, { 1.0F, 0.0F, 0.0F }, { 0.0F, 0.0F } },
|
||||||
{ { 0.5F, -0.5F }, { 0.0F, 1.0F, 0.0F }, { 0.0F, 0.0F } },
|
{ { 0.5F, -0.5F, 0.0F }, { 0.0F, 1.0F, 0.0F }, { 1.0F, 0.0F } },
|
||||||
{ { 0.5F, 0.5F }, { 0.0F, 0.0F, 1.0F }, { 0.0F, 1.0F } },
|
{ { 0.5F, 0.5F, 0.0F }, { 0.0F, 0.0F, 1.0F }, { 1.0F, 1.0F } },
|
||||||
{ { -0.5F, 0.5F }, { 1.0F, 1.0F, 1.0F }, { 1.0F, 1.0F } } }
|
{ { -0.5F, 0.5F, 0.0F }, { 1.0F, 1.0F, 1.0F }, { 0.0F, 1.0F } },
|
||||||
|
{ { -0.5F, -0.5F, -0.5F }, { 1.0F, 0.0F, 0.0F }, { 0.0F, 0.0F } },
|
||||||
|
{ { 0.5F, -0.5F, -0.5F }, { 0.0F, 1.0F, 0.0F }, { 1.0F, 0.0F } },
|
||||||
|
{ { 0.5F, 0.5F, -0.5F }, { 0.0F, 0.0F, 1.0F }, { 1.0F, 1.0F } },
|
||||||
|
{ { -0.5F, 0.5F, -0.5F }, { 1.0F, 1.0F, 1.0F }, { 0.0F, 1.0F } } }
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr std::array<u16, 6> indices = { 0, 1, 2, 2, 3, 0 };
|
// clang-format off
|
||||||
|
constexpr std::array<u16, 12> indices = {
|
||||||
|
0, 1, 2, 2, 3, 0,
|
||||||
|
4, 5, 6, 6, 7, 4
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
class VulkanApp {
|
class VulkanApp {
|
||||||
public:
|
public:
|
||||||
|
@ -105,6 +116,10 @@ class VulkanApp {
|
||||||
|
|
||||||
vk::UniqueCommandPool mCommandPool;
|
vk::UniqueCommandPool mCommandPool;
|
||||||
|
|
||||||
|
vk::UniqueImage mDepthImage;
|
||||||
|
vk::UniqueDeviceMemory mDepthImageMemory;
|
||||||
|
vk::UniqueImageView mDepthImageView;
|
||||||
|
|
||||||
vk::UniqueImage mTextureImage;
|
vk::UniqueImage mTextureImage;
|
||||||
vk::UniqueDeviceMemory mTextureImageMemory;
|
vk::UniqueDeviceMemory mTextureImageMemory;
|
||||||
vk::UniqueImageView mTextureImageView;
|
vk::UniqueImageView mTextureImageView;
|
||||||
|
@ -196,8 +211,9 @@ class VulkanApp {
|
||||||
createRenderPass();
|
createRenderPass();
|
||||||
createDescriptorSetLayout();
|
createDescriptorSetLayout();
|
||||||
createGraphicsPipeline();
|
createGraphicsPipeline();
|
||||||
createFramebuffers();
|
|
||||||
createCommandPool();
|
createCommandPool();
|
||||||
|
createDepthResources();
|
||||||
|
createFramebuffers();
|
||||||
createTextureImage();
|
createTextureImage();
|
||||||
createTextureImageView();
|
createTextureImageView();
|
||||||
createTextureSampler();
|
createTextureSampler();
|
||||||
|
@ -220,10 +236,8 @@ class VulkanApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cleanupSwapChain() -> void {
|
fn cleanupSwapChain() -> void {
|
||||||
for (vk::UniqueFramebuffer& mSwapChainFramebuffer : mSwapChainFramebuffers) {
|
for (vk::UniqueFramebuffer& mSwapChainFramebuffer : mSwapChainFramebuffers) mSwapChainFramebuffer.reset();
|
||||||
mSwapChainFramebuffer.reset();
|
for (vk::UniqueImageView& mSwapChainImageView : mSwapChainImageViews) mSwapChainImageView.reset();
|
||||||
}
|
|
||||||
for (vk::UniqueImageView& mSwapChainImageView : mSwapChainImageViews) { mSwapChainImageView.reset(); }
|
|
||||||
|
|
||||||
mSwapChain.reset();
|
mSwapChain.reset();
|
||||||
}
|
}
|
||||||
|
@ -243,6 +257,7 @@ class VulkanApp {
|
||||||
|
|
||||||
createSwapChain();
|
createSwapChain();
|
||||||
createImageViews();
|
createImageViews();
|
||||||
|
createDepthResources();
|
||||||
createFramebuffers();
|
createFramebuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,26 +430,9 @@ class VulkanApp {
|
||||||
fn createImageViews() -> void {
|
fn createImageViews() -> void {
|
||||||
mSwapChainImageViews.resize(mSwapChainImages.size());
|
mSwapChainImageViews.resize(mSwapChainImages.size());
|
||||||
|
|
||||||
for (u32 i = 0; i < mSwapChainImages.size(); i++) {
|
for (u32 i = 0; i < mSwapChainImages.size(); i++)
|
||||||
vk::ImageViewCreateInfo createInfo {
|
mSwapChainImageViews[i] =
|
||||||
.image = mSwapChainImages[i],
|
createImageView(mSwapChainImages[i], mSwapChainImageFormat, vk::ImageAspectFlagBits::eColor);
|
||||||
.viewType = vk::ImageViewType::e2D,
|
|
||||||
.format = mSwapChainImageFormat,
|
|
||||||
// clang-format off
|
|
||||||
.components = { .r = vk::ComponentSwizzle::eIdentity,
|
|
||||||
.g = vk::ComponentSwizzle::eIdentity,
|
|
||||||
.b = vk::ComponentSwizzle::eIdentity,
|
|
||||||
.a = vk::ComponentSwizzle::eIdentity },
|
|
||||||
.subresourceRange = { .aspectMask = vk::ImageAspectFlagBits::eColor,
|
|
||||||
.baseMipLevel = 0,
|
|
||||||
.levelCount = 1,
|
|
||||||
.baseArrayLayer = 0,
|
|
||||||
.layerCount = 1 },
|
|
||||||
// clang-format on
|
|
||||||
};
|
|
||||||
|
|
||||||
mSwapChainImageViews[i] = mDevice->createImageViewUnique(createInfo);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn createRenderPass() -> void {
|
fn createRenderPass() -> void {
|
||||||
|
@ -449,23 +447,47 @@ class VulkanApp {
|
||||||
.finalLayout = vk::ImageLayout::ePresentSrcKHR,
|
.finalLayout = vk::ImageLayout::ePresentSrcKHR,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
vk::AttachmentDescription depthAttachment { .format = findDepthFormat(),
|
||||||
|
.samples = vk::SampleCountFlagBits::e1,
|
||||||
|
.loadOp = vk::AttachmentLoadOp::eClear,
|
||||||
|
.storeOp = vk::AttachmentStoreOp::eDontCare,
|
||||||
|
.stencilLoadOp = vk::AttachmentLoadOp::eDontCare,
|
||||||
|
.stencilStoreOp = vk::AttachmentStoreOp::eDontCare,
|
||||||
|
.initialLayout = vk::ImageLayout::eUndefined,
|
||||||
|
.finalLayout =
|
||||||
|
vk::ImageLayout::eDepthStencilAttachmentOptimal };
|
||||||
|
|
||||||
vk::AttachmentReference colorAttachmentRef {
|
vk::AttachmentReference colorAttachmentRef {
|
||||||
.attachment = 0,
|
.attachment = 0,
|
||||||
.layout = vk::ImageLayout::eColorAttachmentOptimal,
|
.layout = vk::ImageLayout::eColorAttachmentOptimal,
|
||||||
};
|
};
|
||||||
|
|
||||||
vk::SubpassDescription subpass {
|
vk::AttachmentReference depthAttachmentRef { .attachment = 1,
|
||||||
.pipelineBindPoint = vk::PipelineBindPoint::eGraphics,
|
.layout = vk::ImageLayout::eDepthStencilAttachmentOptimal };
|
||||||
.colorAttachmentCount = 1,
|
|
||||||
.pColorAttachments = &colorAttachmentRef,
|
|
||||||
};
|
|
||||||
|
|
||||||
vk::RenderPassCreateInfo renderPassInfo {
|
vk::SubpassDescription subpass { .pipelineBindPoint = vk::PipelineBindPoint::eGraphics,
|
||||||
.attachmentCount = 1,
|
.colorAttachmentCount = 1,
|
||||||
.pAttachments = &colorAttachment,
|
.pColorAttachments = &colorAttachmentRef,
|
||||||
.subpassCount = 1,
|
.pDepthStencilAttachment = &depthAttachmentRef };
|
||||||
.pSubpasses = &subpass,
|
|
||||||
};
|
vk::SubpassDependency dependency { .srcSubpass = vk::SubpassExternal,
|
||||||
|
.dstSubpass = {},
|
||||||
|
.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput |
|
||||||
|
vk::PipelineStageFlagBits::eEarlyFragmentTests,
|
||||||
|
.dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput |
|
||||||
|
vk::PipelineStageFlagBits::eEarlyFragmentTests,
|
||||||
|
.srcAccessMask = {},
|
||||||
|
.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite |
|
||||||
|
vk::AccessFlagBits::eDepthStencilAttachmentWrite };
|
||||||
|
|
||||||
|
std::array<vk::AttachmentDescription, 2> attachments = { colorAttachment, depthAttachment };
|
||||||
|
|
||||||
|
vk::RenderPassCreateInfo renderPassInfo { .attachmentCount = static_cast<u32>(attachments.size()),
|
||||||
|
.pAttachments = attachments.data(),
|
||||||
|
.subpassCount = 1,
|
||||||
|
.pSubpasses = &subpass,
|
||||||
|
.dependencyCount = 1,
|
||||||
|
.pDependencies = &dependency };
|
||||||
|
|
||||||
mRenderPass = mDevice->createRenderPassUnique(renderPassInfo);
|
mRenderPass = mDevice->createRenderPassUnique(renderPassInfo);
|
||||||
}
|
}
|
||||||
|
@ -504,17 +526,13 @@ class VulkanApp {
|
||||||
vk::UniqueShaderModule vertShaderModule = createShaderModule(vertShaderCode);
|
vk::UniqueShaderModule vertShaderModule = createShaderModule(vertShaderCode);
|
||||||
vk::UniqueShaderModule fragShaderModule = createShaderModule(fragShaderCode);
|
vk::UniqueShaderModule fragShaderModule = createShaderModule(fragShaderCode);
|
||||||
|
|
||||||
vk::PipelineShaderStageCreateInfo vertShaderStageInfo {
|
vk::PipelineShaderStageCreateInfo vertShaderStageInfo { .stage = vk::ShaderStageFlagBits::eVertex,
|
||||||
.stage = vk::ShaderStageFlagBits::eVertex,
|
.module = vertShaderModule.get(),
|
||||||
.module = vertShaderModule.get(),
|
.pName = "main" };
|
||||||
.pName = "main",
|
|
||||||
};
|
|
||||||
|
|
||||||
vk::PipelineShaderStageCreateInfo fragShaderStageInfo {
|
vk::PipelineShaderStageCreateInfo fragShaderStageInfo { .stage = vk::ShaderStageFlagBits::eFragment,
|
||||||
.stage = vk::ShaderStageFlagBits::eFragment,
|
.module = fragShaderModule.get(),
|
||||||
.module = fragShaderModule.get(),
|
.pName = "main" };
|
||||||
.pName = "main",
|
|
||||||
};
|
|
||||||
|
|
||||||
std::array<vk::PipelineShaderStageCreateInfo, 2> shaderStages = { vertShaderStageInfo,
|
std::array<vk::PipelineShaderStageCreateInfo, 2> shaderStages = { vertShaderStageInfo,
|
||||||
fragShaderStageInfo };
|
fragShaderStageInfo };
|
||||||
|
@ -527,38 +545,36 @@ class VulkanApp {
|
||||||
.vertexBindingDescriptionCount = 1,
|
.vertexBindingDescriptionCount = 1,
|
||||||
.pVertexBindingDescriptions = &bindingDescription,
|
.pVertexBindingDescriptions = &bindingDescription,
|
||||||
.vertexAttributeDescriptionCount = static_cast<u32>(attributeDescriptions.size()),
|
.vertexAttributeDescriptionCount = static_cast<u32>(attributeDescriptions.size()),
|
||||||
.pVertexAttributeDescriptions = attributeDescriptions.data(),
|
.pVertexAttributeDescriptions = attributeDescriptions.data()
|
||||||
};
|
};
|
||||||
|
|
||||||
vk::PipelineInputAssemblyStateCreateInfo inputAssembly {
|
vk::PipelineInputAssemblyStateCreateInfo inputAssembly { .topology = vk::PrimitiveTopology::eTriangleList,
|
||||||
.topology = vk::PrimitiveTopology::eTriangleList,
|
.primitiveRestartEnable = vk::False };
|
||||||
.primitiveRestartEnable = vk::False,
|
|
||||||
};
|
|
||||||
|
|
||||||
vk::PipelineViewportStateCreateInfo viewportState {
|
vk::PipelineViewportStateCreateInfo viewportState { .viewportCount = 1, .scissorCount = 1 };
|
||||||
.viewportCount = 1,
|
|
||||||
.scissorCount = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
vk::PipelineRasterizationStateCreateInfo rasterizer {
|
vk::PipelineRasterizationStateCreateInfo rasterizer { .depthClampEnable = vk::False,
|
||||||
.depthClampEnable = vk::False,
|
.rasterizerDiscardEnable = vk::False,
|
||||||
.rasterizerDiscardEnable = vk::False,
|
.polygonMode = vk::PolygonMode::eFill,
|
||||||
.polygonMode = vk::PolygonMode::eFill,
|
.cullMode = vk::CullModeFlagBits::eBack,
|
||||||
.cullMode = vk::CullModeFlagBits::eBack,
|
.frontFace = vk::FrontFace::eCounterClockwise,
|
||||||
.frontFace = vk::FrontFace::eCounterClockwise,
|
.depthBiasEnable = vk::False,
|
||||||
.depthBiasEnable = vk::False,
|
.lineWidth = 1.0F };
|
||||||
.lineWidth = 1.0F,
|
|
||||||
};
|
|
||||||
|
|
||||||
vk::PipelineMultisampleStateCreateInfo multisampling {
|
vk::PipelineMultisampleStateCreateInfo multisampling { .rasterizationSamples =
|
||||||
.rasterizationSamples = vk::SampleCountFlagBits::e1,
|
vk::SampleCountFlagBits::e1,
|
||||||
.sampleShadingEnable = vk::False,
|
.sampleShadingEnable = vk::False };
|
||||||
};
|
|
||||||
|
vk::PipelineDepthStencilStateCreateInfo depthStencil { .depthTestEnable = vk::True,
|
||||||
|
.depthWriteEnable = vk::True,
|
||||||
|
.depthCompareOp = vk::CompareOp::eLess,
|
||||||
|
.depthBoundsTestEnable = vk::False,
|
||||||
|
.stencilTestEnable = vk::False };
|
||||||
|
|
||||||
vk::PipelineColorBlendAttachmentState colorBlendAttachment {
|
vk::PipelineColorBlendAttachmentState colorBlendAttachment {
|
||||||
.blendEnable = vk::False,
|
.blendEnable = vk::False,
|
||||||
.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG |
|
.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG |
|
||||||
vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA,
|
vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA
|
||||||
};
|
};
|
||||||
|
|
||||||
vk::PipelineColorBlendStateCreateInfo colorBlending {
|
vk::PipelineColorBlendStateCreateInfo colorBlending {
|
||||||
|
@ -566,37 +582,33 @@ class VulkanApp {
|
||||||
.logicOp = vk::LogicOp::eCopy,
|
.logicOp = vk::LogicOp::eCopy,
|
||||||
.attachmentCount = 1,
|
.attachmentCount = 1,
|
||||||
.pAttachments = &colorBlendAttachment,
|
.pAttachments = &colorBlendAttachment,
|
||||||
.blendConstants = std::array<float, 4> { 0.0F, 0.0F, 0.0F, 0.0F },
|
.blendConstants = std::array<float, 4> { 0.0F, 0.0F, 0.0F, 0.0F }
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<vk::DynamicState> dynamicStates = { vk::DynamicState::eViewport, vk::DynamicState::eScissor };
|
std::vector<vk::DynamicState> dynamicStates = { vk::DynamicState::eViewport, vk::DynamicState::eScissor };
|
||||||
|
|
||||||
vk::PipelineDynamicStateCreateInfo dynamicState {
|
vk::PipelineDynamicStateCreateInfo dynamicState { .dynamicStateCount =
|
||||||
.dynamicStateCount = static_cast<u32>(dynamicStates.size()),
|
static_cast<u32>(dynamicStates.size()),
|
||||||
.pDynamicStates = dynamicStates.data(),
|
.pDynamicStates = dynamicStates.data() };
|
||||||
};
|
|
||||||
|
|
||||||
vk::PipelineLayoutCreateInfo pipelineLayoutInfo {
|
vk::PipelineLayoutCreateInfo pipelineLayoutInfo { .setLayoutCount = 1,
|
||||||
.setLayoutCount = 1,
|
.pSetLayouts = &mDescriptorSetLayout.get() };
|
||||||
.pSetLayouts = &mDescriptorSetLayout.get(),
|
|
||||||
};
|
|
||||||
|
|
||||||
mPipelineLayout = mDevice->createPipelineLayoutUnique(pipelineLayoutInfo);
|
mPipelineLayout = mDevice->createPipelineLayoutUnique(pipelineLayoutInfo);
|
||||||
|
|
||||||
vk::GraphicsPipelineCreateInfo pipelineInfo {
|
vk::GraphicsPipelineCreateInfo pipelineInfo { .stageCount = static_cast<u32>(shaderStages.size()),
|
||||||
.stageCount = static_cast<u32>(shaderStages.size()),
|
.pStages = shaderStages.data(),
|
||||||
.pStages = shaderStages.data(),
|
.pVertexInputState = &vertexInputInfo,
|
||||||
.pVertexInputState = &vertexInputInfo,
|
.pInputAssemblyState = &inputAssembly,
|
||||||
.pInputAssemblyState = &inputAssembly,
|
.pViewportState = &viewportState,
|
||||||
.pViewportState = &viewportState,
|
.pRasterizationState = &rasterizer,
|
||||||
.pRasterizationState = &rasterizer,
|
.pMultisampleState = &multisampling,
|
||||||
.pMultisampleState = &multisampling,
|
.pDepthStencilState = &depthStencil,
|
||||||
.pColorBlendState = &colorBlending,
|
.pColorBlendState = &colorBlending,
|
||||||
.pDynamicState = &dynamicState,
|
.pDynamicState = &dynamicState,
|
||||||
.layout = mPipelineLayout.get(),
|
.layout = mPipelineLayout.get(),
|
||||||
.renderPass = mRenderPass.get(),
|
.renderPass = mRenderPass.get(),
|
||||||
.subpass = 0,
|
.subpass = 0 };
|
||||||
};
|
|
||||||
|
|
||||||
vk::Result graphicsPipelineResult = vk::Result::eSuccess;
|
vk::Result graphicsPipelineResult = vk::Result::eSuccess;
|
||||||
vk::UniquePipeline graphicsPipelineValue;
|
vk::UniquePipeline graphicsPipelineValue;
|
||||||
|
@ -614,14 +626,14 @@ class VulkanApp {
|
||||||
mSwapChainFramebuffers.resize(mSwapChainImageViews.size());
|
mSwapChainFramebuffers.resize(mSwapChainImageViews.size());
|
||||||
|
|
||||||
for (usize i = 0; i < mSwapChainImageViews.size(); i++) {
|
for (usize i = 0; i < mSwapChainImageViews.size(); i++) {
|
||||||
vk::FramebufferCreateInfo framebufferInfo {
|
std::array<vk::ImageView, 2> attachments = { mSwapChainImageViews[i].get(), mDepthImageView.get() };
|
||||||
.renderPass = mRenderPass.get(),
|
|
||||||
.attachmentCount = 1,
|
vk::FramebufferCreateInfo framebufferInfo { .renderPass = mRenderPass.get(),
|
||||||
.pAttachments = &mSwapChainImageViews[i].get(),
|
.attachmentCount = static_cast<u32>(attachments.size()),
|
||||||
.width = mSwapChainExtent.width,
|
.pAttachments = attachments.data(),
|
||||||
.height = mSwapChainExtent.height,
|
.width = mSwapChainExtent.width,
|
||||||
.layers = 1,
|
.height = mSwapChainExtent.height,
|
||||||
};
|
.layers = 1 };
|
||||||
|
|
||||||
mSwapChainFramebuffers[i] = mDevice->createFramebufferUnique(framebufferInfo);
|
mSwapChainFramebuffers[i] = mDevice->createFramebufferUnique(framebufferInfo);
|
||||||
}
|
}
|
||||||
|
@ -638,6 +650,51 @@ class VulkanApp {
|
||||||
mCommandPool = mDevice->createCommandPoolUnique(poolInfo);
|
mCommandPool = mDevice->createCommandPoolUnique(poolInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn createDepthResources() -> void {
|
||||||
|
vk::Format depthFormat = findDepthFormat();
|
||||||
|
|
||||||
|
createImage(
|
||||||
|
mSwapChainExtent.width,
|
||||||
|
mSwapChainExtent.height,
|
||||||
|
depthFormat,
|
||||||
|
vk::ImageTiling::eOptimal,
|
||||||
|
vk::ImageUsageFlagBits::eDepthStencilAttachment,
|
||||||
|
vk::MemoryPropertyFlagBits::eDeviceLocal,
|
||||||
|
mDepthImage,
|
||||||
|
mDepthImageMemory
|
||||||
|
);
|
||||||
|
|
||||||
|
mDepthImageView = createImageView(mDepthImage.get(), depthFormat, vk::ImageAspectFlagBits::eDepth);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn findSupportedFormat(
|
||||||
|
const std::vector<vk::Format>& candidates,
|
||||||
|
vk::ImageTiling tiling,
|
||||||
|
vk::FormatFeatureFlags features
|
||||||
|
) -> vk::Format {
|
||||||
|
for (vk::Format format : candidates) {
|
||||||
|
vk::FormatProperties props = mPhysicalDevice.getFormatProperties(format);
|
||||||
|
if (tiling == vk::ImageTiling::eLinear && (props.linearTilingFeatures & features) == features)
|
||||||
|
return format;
|
||||||
|
if (tiling == vk::ImageTiling::eOptimal && (props.optimalTilingFeatures & features) == features)
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::runtime_error("Failed to find supported format!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn findDepthFormat() -> vk::Format {
|
||||||
|
return findSupportedFormat(
|
||||||
|
{ vk::Format::eD32Sfloat, vk::Format::eD32SfloatS8Uint, vk::Format::eD24UnormS8Uint },
|
||||||
|
vk::ImageTiling::eOptimal,
|
||||||
|
vk::FormatFeatureFlagBits::eDepthStencilAttachment
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static fn hasStencilComponent(vk::Format format) {
|
||||||
|
return format == vk::Format::eD32SfloatS8Uint || format == vk::Format::eD24UnormS8Uint;
|
||||||
|
}
|
||||||
|
|
||||||
fn createTextureImage() -> void {
|
fn createTextureImage() -> void {
|
||||||
i32 texWidth = 0, texHeight = 0, texChannels = 0;
|
i32 texWidth = 0, texHeight = 0, texChannels = 0;
|
||||||
u8* pixels = stbi_load("src/textures/texture.jpg", &texWidth, &texHeight, &texChannels, STBI_rgb_alpha);
|
u8* pixels = stbi_load("src/textures/texture.jpg", &texWidth, &texHeight, &texChannels, STBI_rgb_alpha);
|
||||||
|
@ -783,8 +840,6 @@ class VulkanApp {
|
||||||
vk::UniqueCommandBuffer commandBuffer = beginSingleTimeCommands();
|
vk::UniqueCommandBuffer commandBuffer = beginSingleTimeCommands();
|
||||||
|
|
||||||
vk::ImageMemoryBarrier barrier {
|
vk::ImageMemoryBarrier barrier {
|
||||||
.srcAccessMask = { },
|
|
||||||
.dstAccessMask = { },
|
|
||||||
.oldLayout = oldLayout,
|
.oldLayout = oldLayout,
|
||||||
.newLayout = newLayout,
|
.newLayout = newLayout,
|
||||||
.srcQueueFamilyIndex = vk::QueueFamilyIgnored,
|
.srcQueueFamilyIndex = vk::QueueFamilyIgnored,
|
||||||
|
@ -795,7 +850,7 @@ class VulkanApp {
|
||||||
.baseMipLevel = 0,
|
.baseMipLevel = 0,
|
||||||
.levelCount = 1,
|
.levelCount = 1,
|
||||||
.baseArrayLayer = 0,
|
.baseArrayLayer = 0,
|
||||||
.layerCount = 1 },
|
.layerCount = 1 }
|
||||||
// clang-format on
|
// clang-format on
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1080,14 +1135,17 @@ class VulkanApp {
|
||||||
|
|
||||||
commandBuffer.begin(beginInfo);
|
commandBuffer.begin(beginInfo);
|
||||||
|
|
||||||
vk::ClearValue clearColor { .color = { .float32 = std::array<float, 4> { 0.0F, 0.0F, 0.0F, 1.0F } } };
|
std::array<vk::ClearValue, 2> clearValues {
|
||||||
|
{ { .color = { .float32 = std::array<float, 4> { 0.0F, 0.0F, 0.0F, 1.0F } } },
|
||||||
|
{ .depthStencil = { .depth = 1.0F, .stencil = 0 } } }
|
||||||
|
};
|
||||||
|
|
||||||
vk::RenderPassBeginInfo renderPassInfo {
|
vk::RenderPassBeginInfo renderPassInfo {
|
||||||
.renderPass = mRenderPass.get(),
|
.renderPass = mRenderPass.get(),
|
||||||
.framebuffer = mSwapChainFramebuffers[imageIndex].get(),
|
.framebuffer = mSwapChainFramebuffers[imageIndex].get(),
|
||||||
.renderArea = { .offset = { .x = 0, .y = 0 }, .extent = mSwapChainExtent },
|
.renderArea = { .offset = { .x = 0, .y = 0 }, .extent = mSwapChainExtent },
|
||||||
.clearValueCount = 1,
|
.clearValueCount = static_cast<u32>(clearValues.size()),
|
||||||
.pClearValues = &clearColor,
|
.pClearValues = clearValues.data()
|
||||||
};
|
};
|
||||||
|
|
||||||
commandBuffer.beginRenderPass(renderPassInfo, vk::SubpassContents::eInline);
|
commandBuffer.beginRenderPass(renderPassInfo, vk::SubpassContents::eInline);
|
||||||
|
@ -1226,8 +1284,6 @@ class VulkanApp {
|
||||||
|
|
||||||
vk::Result presentResult = mPresentQueue.presentKHR(presentInfo);
|
vk::Result presentResult = mPresentQueue.presentKHR(presentInfo);
|
||||||
|
|
||||||
fmt::println("Present result: {}", vk::to_string(presentResult));
|
|
||||||
|
|
||||||
if (presentResult == vk::Result::eErrorOutOfDateKHR || presentResult == vk::Result::eSuboptimalKHR ||
|
if (presentResult == vk::Result::eErrorOutOfDateKHR || presentResult == vk::Result::eSuboptimalKHR ||
|
||||||
mFramebufferResized) {
|
mFramebufferResized) {
|
||||||
mFramebufferResized = false;
|
mFramebufferResized = false;
|
||||||
|
|
|
@ -6,7 +6,7 @@ layout(binding = 0) uniform UniformBufferObject {
|
||||||
mat4 proj;
|
mat4 proj;
|
||||||
} ubo;
|
} ubo;
|
||||||
|
|
||||||
layout(location = 0) in vec2 inPosition;
|
layout(location = 0) in vec3 inPosition;
|
||||||
layout(location = 1) in vec3 inColor;
|
layout(location = 1) in vec3 inColor;
|
||||||
layout(location = 2) in vec2 inTexCoord;
|
layout(location = 2) in vec2 inTexCoord;
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ layout(location = 0) out vec3 fragColor;
|
||||||
layout(location = 1) out vec2 fragTexCoord;
|
layout(location = 1) out vec2 fragTexCoord;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 0.0, 1.0);
|
gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 1.0);
|
||||||
fragColor = inColor;
|
fragColor = inColor;
|
||||||
fragTexCoord = inTexCoord;
|
fragTexCoord = inTexCoord;
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
Loading…
Reference in a new issue