diff --git a/NothinFancy/src/client/render/Buffer.cpp b/NothinFancy/src/client/render/Buffer.cpp index ab59a68..920c909 100644 --- a/NothinFancy/src/client/render/Buffer.cpp +++ b/NothinFancy/src/client/render/Buffer.cpp @@ -75,29 +75,22 @@ namespace nf::client::render { VkCommandBufferAllocateInfo commandBufferAI = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; commandBufferAI.commandPool = commandPool; commandBufferAI.commandBufferCount = 1; - - if (vkAllocateCommandBuffers(m_device, &commandBufferAI, &commandBuffer) != VK_SUCCESS) - NFError("Could not create command buffer."); + vkAllocateCommandBuffers(m_device, &commandBufferAI, &commandBuffer); VkCommandBufferBeginInfo commandBufferBI = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; commandBufferBI.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - vkBeginCommandBuffer(commandBuffer, &commandBufferBI); VkBufferCopy bufferCopyRegion = {}; bufferCopyRegion.size = size; vkCmdCopyBuffer(commandBuffer, bufferSource, bufferDestination, 1, &bufferCopyRegion); - if (vkEndCommandBuffer(commandBuffer) != VK_SUCCESS) - NFError("Could not end command buffer."); + vkEndCommandBuffer(commandBuffer); VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO }; submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &commandBuffer; - - if (vkQueueSubmit(queue, 1, &submitInfo, nullptr) != VK_SUCCESS) - NFError("Could not submit to Vulkan queue."); - + vkQueueSubmit(queue, 1, &submitInfo, nullptr); vkQueueWaitIdle(queue); vkFreeCommandBuffers(m_device, commandPool, 1, &commandBuffer); diff --git a/NothinFancy/src/client/render/Image.cpp b/NothinFancy/src/client/render/Image.cpp index 613076e..bbf4ee9 100644 --- a/NothinFancy/src/client/render/Image.cpp +++ b/NothinFancy/src/client/render/Image.cpp @@ -9,36 +9,46 @@ #include "stb_image.h" namespace nf::client::render { - Image::Image(const VkDevice& device, VideoMemoryAllocator& allocator, const VkCommandPool& commandPool, const VkQueue& queue, const std::string& imageData) + Image::Image(ImageType type, const VkDevice& device, VideoMemoryAllocator& allocator, const VkCommandPool& commandPool, const VkQueue& queue, const std::string& imageData, VkExtent2D attachmentExtent) : GraphicsResource(device) , m_allocator(allocator) , m_handle() , m_allocation() , m_view() { + VkFormat imageFormat = VK_FORMAT_UNDEFINED; + + switch (type) { + case ImageType::Texture: + imageFormat = VK_FORMAT_R8G8B8A8_SRGB; + createTextureImage(imageFormat, commandPool, queue, imageData); + break; + + case ImageType::DepthAttachment: + imageFormat = VK_FORMAT_D32_SFLOAT; + createImage(imageFormat, attachmentExtent, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); + break; + } + + createImageView(imageFormat); + } + + const VkImageView& Image::getView() const { + return m_view; + } + + void Image::createTextureImage(VkFormat imageFormat, const VkCommandPool& commandPool, const VkQueue& queue, const std::string& imageData) { int imageWidth = 0, imageHeight = 0, numChannels = 0; stbi_uc* rawImageData = stbi_load_from_memory(reinterpret_cast(imageData.data()), imageData.size(), &imageWidth, &imageHeight, &numChannels, STBI_rgb_alpha); - VkDeviceSize imageSize = imageWidth * imageHeight * 4; + VkDeviceSize imageSize = static_cast(imageWidth) * imageHeight * 4; Buffer stagingBuffer(BufferType::Staging, m_device, m_allocator, nullptr, nullptr, rawImageData, imageSize); stbi_image_free(rawImageData); - VkImageCreateInfo imageCI = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO }; - imageCI.imageType = VK_IMAGE_TYPE_2D; - imageCI.extent.width = imageWidth, imageCI.extent.height = imageHeight, imageCI.extent.depth = 1; - imageCI.mipLevels = 1; - imageCI.arrayLayers = 1; - imageCI.samples = VK_SAMPLE_COUNT_1_BIT; - imageCI.format = VK_FORMAT_R8G8B8A8_SRGB; - imageCI.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; - imageCI.tiling = VK_IMAGE_TILING_OPTIMAL; - - if (vkCreateImage(m_device, &imageCI, nullptr, &m_handle) != VK_SUCCESS) - NFError("Could not create image."); - - m_allocator.allocateForImage(m_handle, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, m_allocation); + VkExtent2D imageExtent = { static_cast(imageWidth), static_cast(imageHeight) }; + createImage(imageFormat, imageExtent, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); VkCommandBuffer commandBuffer = nullptr; VkCommandBufferAllocateInfo commandBufferAI = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; @@ -48,7 +58,6 @@ namespace nf::client::render { VkCommandBufferBeginInfo commandBufferBI = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; commandBufferBI.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - vkBeginCommandBuffer(commandBuffer, &commandBufferBI); // Image transition undefined -> transfer destination @@ -63,6 +72,7 @@ namespace nf::client::render { imageMemoryBarrier.srcAccessMask = 0; imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier); + vkEndCommandBuffer(commandBuffer); VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO }; @@ -91,18 +101,41 @@ namespace nf::client::render { imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier); + vkEndCommandBuffer(commandBuffer); vkQueueSubmit(queue, 1, &submitInfo, nullptr); vkQueueWaitIdle(queue); vkFreeCommandBuffers(m_device, commandPool, 1, &commandBuffer); + } + + void Image::createImage(VkFormat format, VkExtent2D& size, VkImageUsageFlags usage) { + VkImageCreateInfo imageCI = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO }; + imageCI.imageType = VK_IMAGE_TYPE_2D; + imageCI.extent = { size.width, size.height, 1 }; + imageCI.mipLevels = 1; + imageCI.arrayLayers = 1; + imageCI.samples = VK_SAMPLE_COUNT_1_BIT; + imageCI.format = format; + imageCI.usage = usage; + imageCI.tiling = VK_IMAGE_TILING_OPTIMAL; + + if (vkCreateImage(m_device, &imageCI, nullptr, &m_handle) != VK_SUCCESS) + NFError("Could not create image."); + + m_allocator.allocateForImage(m_handle, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, m_allocation); + } + + void Image::createImageView(VkFormat format) { + VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + if (format == VK_FORMAT_D32_SFLOAT) + aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; - // Create image view VkImageViewCreateInfo imageViewCI = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO }; imageViewCI.image = m_handle; imageViewCI.viewType = VK_IMAGE_VIEW_TYPE_2D; - imageViewCI.format = VK_FORMAT_R8G8B8A8_SRGB; - imageViewCI.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + imageViewCI.format = format; + imageViewCI.subresourceRange.aspectMask = aspectMask; imageViewCI.subresourceRange.levelCount = 1; imageViewCI.subresourceRange.layerCount = 1; @@ -110,10 +143,6 @@ namespace nf::client::render { NFError("Could not create image view."); } - const VkImageView& Image::getView() const { - return m_view; - } - Image::~Image() { vkDestroyImageView(m_device, m_view, nullptr); m_allocator.deallocate(m_allocation); diff --git a/NothinFancy/src/client/render/Image.h b/NothinFancy/src/client/render/Image.h index 111e6be..c107482 100644 --- a/NothinFancy/src/client/render/Image.h +++ b/NothinFancy/src/client/render/Image.h @@ -5,14 +5,23 @@ #include "VideoMemoryAllocator.h" namespace nf::client::render { + enum class ImageType { + Texture, + DepthAttachment + }; + class Image : GraphicsResource { public: - Image(const VkDevice& device, VideoMemoryAllocator& allocator, const VkCommandPool& commandPool, const VkQueue& queue, const std::string& data); + Image(ImageType type, const VkDevice& device, VideoMemoryAllocator& allocator, const VkCommandPool& commandPool, const VkQueue& queue, const std::string& imageData, VkExtent2D attachmentExtent = {}); const VkImageView& getView() const; ~Image(); private: + void createTextureImage(VkFormat imageFormat, const VkCommandPool& commandPool, const VkQueue& queue, const std::string& imageData); + void createImage(VkFormat imageFormat, VkExtent2D& size, VkImageUsageFlags usage); + void createImageView(VkFormat format); + VideoMemoryAllocator& m_allocator; VkImage m_handle; diff --git a/NothinFancy/src/client/render/RenderEngine.cpp b/NothinFancy/src/client/render/RenderEngine.cpp index a1d89ba..e2f6afb 100644 --- a/NothinFancy/src/client/render/RenderEngine.cpp +++ b/NothinFancy/src/client/render/RenderEngine.cpp @@ -29,7 +29,6 @@ namespace nf::client::render { , m_swapchainExtent() , m_swapchainImages() , m_swapchainImageViews() - , m_swapchainFramebuffers() , m_pipelineOutputDescriptorSetLayout() , m_pipelineOutputLayout() , m_pipelineOutputDescriptorPool() @@ -40,6 +39,8 @@ namespace nf::client::render { , m_semaphoreRenderingDone() , m_fenceFrameInFlight() , m_allocator() + , m_swapchainFramebuffers() + , m_imageDepth() , m_bufferVertex() , m_bufferIndex() , m_imageTest() @@ -56,11 +57,11 @@ namespace nf::client::render { createDevice(); createSwapchain(); createOutputRenderPass(); - createSwapchainFramebuffers(); createOutputPipeline(); createExecutionObjects(); m_allocator = std::make_unique(m_device, m_physicalDevice); + createSwapchainFramebuffers(); createBuffers(); createImage(); createDescriptorSet(); @@ -285,34 +286,46 @@ namespace nf::client::render { } void RenderEngine::createOutputRenderPass() { - VkAttachmentDescription outputColorAttachment = {}; - outputColorAttachment.format = m_swapchainImageFormat; - outputColorAttachment.samples = VK_SAMPLE_COUNT_1_BIT; - outputColorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - outputColorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - outputColorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - outputColorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - outputColorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - outputColorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + VkAttachmentDescription attachmentDescriptions[2] = {}; - VkAttachmentReference outputColorAttachmentReference = {}; - outputColorAttachmentReference.attachment = 0; - outputColorAttachmentReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + // Color attachment + attachmentDescriptions[0].format = m_swapchainImageFormat; + attachmentDescriptions[0].samples = VK_SAMPLE_COUNT_1_BIT; + attachmentDescriptions[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + attachmentDescriptions[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attachmentDescriptions[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachmentDescriptions[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachmentDescriptions[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + attachmentDescriptions[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + + // Depth attachment + attachmentDescriptions[1] = attachmentDescriptions[0]; + attachmentDescriptions[1].format = VK_FORMAT_D32_SFLOAT; + attachmentDescriptions[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + + VkAttachmentReference attachmentReferences[2] = {}; + attachmentReferences[0].attachment = 0; + attachmentReferences[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + attachmentReferences[1].attachment = 1; + attachmentReferences[1].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; VkSubpassDescription subpassDescription = {}; subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; subpassDescription.colorAttachmentCount = 1; - subpassDescription.pColorAttachments = &outputColorAttachmentReference; + subpassDescription.pColorAttachments = &attachmentReferences[0]; + subpassDescription.pDepthStencilAttachment = &attachmentReferences[1]; VkSubpassDependency dependency = {}; dependency.srcSubpass = VK_SUBPASS_EXTERNAL; - dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + dependency.dstSubpass = 0; + dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + dependency.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; + dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; VkRenderPassCreateInfo renderPassCI = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO }; - renderPassCI.attachmentCount = 1; - renderPassCI.pAttachments = &outputColorAttachment; + renderPassCI.attachmentCount = 2; + renderPassCI.pAttachments = attachmentDescriptions; renderPassCI.subpassCount = 1; renderPassCI.pSubpasses = &subpassDescription; renderPassCI.dependencyCount = 1; @@ -322,22 +335,6 @@ namespace nf::client::render { NFError("Could not create Vulkan output render pass."); } - void RenderEngine::createSwapchainFramebuffers() { - // TODO: Won't need these forever - m_swapchainFramebuffers.resize(m_swapchainImageViews.size()); - for (int i = 0; i < m_swapchainImageViews.size(); i++) { - VkFramebufferCreateInfo framebufferCI = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO }; - framebufferCI.renderPass = m_renderPassOutput; - framebufferCI.attachmentCount = 1; - framebufferCI.pAttachments = &m_swapchainImageViews[i]; - framebufferCI.width = m_swapchainExtent.width, framebufferCI.height = m_swapchainExtent.height; - framebufferCI.layers = 1; - - if (vkCreateFramebuffer(m_device, &framebufferCI, nullptr, &m_swapchainFramebuffers[i]) != VK_SUCCESS) - NFError("Could not create framebuffer."); - } - } - void RenderEngine::createOutputPipeline() { // First, create shader modules std::string outputShaderVertexBinary, outputShaderFragmentBinary; @@ -365,7 +362,7 @@ namespace nf::client::render { VkPipelineVertexInputStateCreateInfo vertexInputStateCI = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO }; VkVertexInputBindingDescription vertexBindingDescription = {}; vertexBindingDescription.stride = sizeof(Vertex); - std::array vertexAttributeDescriptions = {}; + VkVertexInputAttributeDescription vertexAttributeDescriptions[2] = {}; vertexAttributeDescriptions[0].location = 0; vertexAttributeDescriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT; vertexAttributeDescriptions[0].offset = offsetof(Vertex, position); @@ -374,8 +371,8 @@ namespace nf::client::render { vertexAttributeDescriptions[1].offset = offsetof(Vertex, textureCoordinates); vertexInputStateCI.vertexBindingDescriptionCount = 1; vertexInputStateCI.pVertexBindingDescriptions = &vertexBindingDescription; - vertexInputStateCI.vertexAttributeDescriptionCount = vertexAttributeDescriptions.size(); - vertexInputStateCI.pVertexAttributeDescriptions = vertexAttributeDescriptions.data(); + vertexInputStateCI.vertexAttributeDescriptionCount = 2; + vertexInputStateCI.pVertexAttributeDescriptions = vertexAttributeDescriptions; // Specify input assembly state VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCI = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO }; @@ -396,6 +393,12 @@ namespace nf::client::render { VkPipelineMultisampleStateCreateInfo multisampleStateCI = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; multisampleStateCI.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + // Specify depth stencil state + VkPipelineDepthStencilStateCreateInfo depthStencilStateCI = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO }; + depthStencilStateCI.depthTestEnable = VK_TRUE; + depthStencilStateCI.depthWriteEnable = VK_TRUE; + depthStencilStateCI.depthCompareOp = VK_COMPARE_OP_LESS; + // Specify color blend state VkPipelineColorBlendAttachmentState colorBlendAttachmentState = {}; colorBlendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; @@ -452,6 +455,7 @@ namespace nf::client::render { pipelineCI.pViewportState = &viewportStateCI; pipelineCI.pRasterizationState = &rasterizationCI; pipelineCI.pMultisampleState = &multisampleStateCI; + pipelineCI.pDepthStencilState = &depthStencilStateCI; pipelineCI.pColorBlendState = &colorBlendStateCI; pipelineCI.pDynamicState = &dynamicStateCI; pipelineCI.layout = m_pipelineOutputLayout; @@ -487,6 +491,27 @@ namespace nf::client::render { NFError("Could not create fence."); } + void RenderEngine::createSwapchainFramebuffers() { + // TODO: Won't need these forever + + // Create depth buffer first + m_imageDepth = std::make_unique(ImageType::DepthAttachment, m_device, *m_allocator, nullptr, nullptr, std::string(), m_swapchainExtent); + + m_swapchainFramebuffers.resize(m_swapchainImageViews.size()); + for (int i = 0; i < m_swapchainImageViews.size(); i++) { + VkFramebufferCreateInfo framebufferCI = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO }; + framebufferCI.renderPass = m_renderPassOutput; + VkImageView views[] = { m_swapchainImageViews[i], m_imageDepth->getView() }; + framebufferCI.attachmentCount = 2; + framebufferCI.pAttachments = views; + framebufferCI.width = m_swapchainExtent.width, framebufferCI.height = m_swapchainExtent.height; + framebufferCI.layers = 1; + + if (vkCreateFramebuffer(m_device, &framebufferCI, nullptr, &m_swapchainFramebuffers[i]) != VK_SUCCESS) + NFError("Could not create framebuffer."); + } + } + void RenderEngine::createBuffers() { std::vector cubeVertices = { {{-0.5, -0.5, 0.5}, {0.0, 1.0}}, @@ -517,7 +542,11 @@ namespace nf::client::render { {{ 0.5, 0.5, -0.5}, {1.0, 0.0}}, {{-0.5, 0.5, -0.5}, {0.0, 0.0}}, {{-0.5, -0.5, -0.5}, {0.0, 1.0}}, - {{ 0.5, -0.5, -0.5}, {1.0, 1.0}} + {{ 0.5, -0.5, -0.5}, {1.0, 1.0}}, + + {{ 0.5, -0.6, 0.5}, {1.0, 1.0}}, + {{ 0.5, -0.6, -0.5}, {1.0, 0.0}}, + {{-0.5, -0.6, 0.5}, {0.0, 1.0}} }; size_t cubeVerticesSize = sizeof(cubeVertices[0]) * cubeVertices.size(); @@ -540,7 +569,9 @@ namespace nf::client::render { 17, 19, 18, 20, 23, 21, - 23, 22, 21 + 23, 22, 21, + + 24, 25, 26 }; size_t cubeIndicesSize = sizeof(cubeIndices[0]) * cubeIndices.size(); @@ -553,7 +584,7 @@ namespace nf::client::render { void RenderEngine::createImage() { std::string imageData; util::readFile("grayson.jpg", imageData); - m_imageTest = std::make_unique(m_device, *m_allocator, m_commandPool, m_queueGraphics, imageData); + m_imageTest = std::make_unique(ImageType::Texture, m_device, *m_allocator, m_commandPool, m_queueGraphics, imageData); VkSamplerCreateInfo samplerCI = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO }; samplerCI.magFilter = samplerCI.minFilter = VK_FILTER_LINEAR; @@ -617,13 +648,13 @@ namespace nf::client::render { vkBeginCommandBuffer(m_commandBuffer, &commandBufferBI); // Start the render pass - VkClearValue black = { {{0.0, 0.0, 0.0, 1.0}} }; + VkClearValue clearValues[] = { {{0.0, 0.0, 0.0, 1.0}}, {1.0, 0} }; VkRenderPassBeginInfo renderPassBI = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO }; renderPassBI.renderPass = m_renderPassOutput; renderPassBI.framebuffer = m_swapchainFramebuffers[nextImageIndex]; renderPassBI.renderArea.extent = m_swapchainExtent; - renderPassBI.clearValueCount = 1; - renderPassBI.pClearValues = &black; + renderPassBI.clearValueCount = 2; + renderPassBI.pClearValues = clearValues; vkCmdBeginRenderPass(m_commandBuffer, &renderPassBI, VK_SUBPASS_CONTENTS_INLINE); // Bind output pipeline @@ -646,7 +677,7 @@ namespace nf::client::render { static auto startTime = std::chrono::high_resolution_clock::now(); auto currentTime = std::chrono::high_resolution_clock::now(); float time = std::chrono::duration(currentTime - startTime).count(); - glm::mat4 modelMatrix = glm::rotate(glm::mat4(1.0), time * glm::radians(20.0f), glm::vec3(0.0, 0.0, 1.0)), + glm::mat4 modelMatrix = glm::rotate(glm::mat4(1.0), time * glm::radians(20.0f), glm::vec3(0.0, 1.0, 0.0)), viewMatrix = glm::lookAt(glm::vec3(1.0, 1.0, 2.0), glm::vec3(0.0), glm::vec3(0.0, 1.0, 0.0)), projectionMatrix = glm::perspective(glm::radians(45.0f), static_cast(m_swapchainExtent.width) / m_swapchainExtent.height, 0.1f, 10.0f); @@ -664,8 +695,7 @@ namespace nf::client::render { vkCmdEndRenderPass(m_commandBuffer); // Finish recording - if (vkEndCommandBuffer(m_commandBuffer) != VK_SUCCESS) - NFError("Could not end command buffer."); + vkEndCommandBuffer(m_commandBuffer); // Submit to graphics queue VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; @@ -718,6 +748,8 @@ namespace nf::client::render { for (int i = 0; i < m_swapchainFramebuffers.size(); i++) vkDestroyFramebuffer(m_device, m_swapchainFramebuffers[i], nullptr); + m_imageDepth.reset(); + for (int i = 0; i < m_swapchainImageViews.size(); i++) vkDestroyImageView(m_device, m_swapchainImageViews[i], nullptr); diff --git a/NothinFancy/src/client/render/RenderEngine.h b/NothinFancy/src/client/render/RenderEngine.h index 3693c9b..11f5276 100644 --- a/NothinFancy/src/client/render/RenderEngine.h +++ b/NothinFancy/src/client/render/RenderEngine.h @@ -24,10 +24,10 @@ namespace nf::client::render { void createSwapchain(); void createOutputRenderPass(); - void createSwapchainFramebuffers(); void createOutputPipeline(); void createExecutionObjects(); + void createSwapchainFramebuffers(); void createBuffers(); void createImage(); void createDescriptorSet(); @@ -56,7 +56,6 @@ namespace nf::client::render { VkExtent2D m_swapchainExtent; std::vector m_swapchainImages; std::vector m_swapchainImageViews; - std::vector m_swapchainFramebuffers; // Pipelines VkDescriptorSetLayout m_pipelineOutputDescriptorSetLayout; @@ -73,6 +72,8 @@ namespace nf::client::render { // Temporary objects std::unique_ptr m_allocator; + std::unique_ptr m_imageDepth; + std::vector m_swapchainFramebuffers; std::unique_ptr m_bufferVertex; std::unique_ptr m_bufferIndex; std::unique_ptr m_bufferUniformMVP; diff --git a/NothinFancy/src/pch.h b/NothinFancy/src/pch.h index 6a33947..cc00518 100644 --- a/NothinFancy/src/pch.h +++ b/NothinFancy/src/pch.h @@ -44,5 +44,6 @@ #include // GLM +#define GLM_FORCE_DEPTH_ZERO_TO_ONE #include #include