From dd0dc5fbcfd77e567cf8bb26322c4bee05006e20 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sun, 9 Jul 2023 11:53:12 -0400 Subject: [PATCH] Allow no material meshes with a dummy texture instead --- parts/mdl/CMakeLists.txt | 1 + renderer/include/renderer.hpp | 8 ++ renderer/src/renderer.cpp | 151 +++++++++++++++++++++++++++++++--- 3 files changed, 149 insertions(+), 11 deletions(-) diff --git a/parts/mdl/CMakeLists.txt b/parts/mdl/CMakeLists.txt index f968459..5d57df3 100644 --- a/parts/mdl/CMakeLists.txt +++ b/parts/mdl/CMakeLists.txt @@ -1,4 +1,5 @@ find_package(assimp REQUIRED) +set_target_properties(assimp::assimp PROPERTIES MAP_IMPORTED_CONFIG_DEBUG Release) add_library(mdlpart STATIC mdlpart.cpp) target_link_libraries(mdlpart PUBLIC physis z ${LIBRARIES} Qt5::Core Qt5::Widgets renderer NovusCommon assimp::assimp) diff --git a/renderer/include/renderer.hpp b/renderer/include/renderer.hpp index 90a1083..1ded925 100644 --- a/renderer/include/renderer.hpp +++ b/renderer/include/renderer.hpp @@ -83,6 +83,11 @@ public: VkDeviceMemory depthMemory; VkImageView depthView; + VkImage dummyImage; + VkDeviceMemory dummyMemory; + VkImageView dummyView; + VkSampler dummySampler; + VkDescriptorPool descriptorPool = VK_NULL_HANDLE; VkDescriptorSetLayout setLayout = VK_NULL_HANDLE; @@ -115,4 +120,7 @@ public: int hash(const RenderModel& model, const RenderMaterial& material); glm::mat4 view; + +private: + void createDummyTexture(); }; \ No newline at end of file diff --git a/renderer/src/renderer.cpp b/renderer/src/renderer.cpp index 1f63eef..c7cf9b1 100644 --- a/renderer/src/renderer.cpp +++ b/renderer/src/renderer.cpp @@ -194,6 +194,8 @@ Renderer::Renderer() { vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool); + createDummyTexture(); + fmt::print("Initialized renderer!\n"); } @@ -496,7 +498,6 @@ void Renderer::render(std::vector models) { vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &cachedDescriptors[h], 0, nullptr); - VkDeviceSize offsets[] = {0}; vkCmdBindVertexBuffers(commandBuffer, 0, 1, &part.vertexBuffer, offsets); vkCmdBindIndexBuffer(commandBuffer, part.indexBuffer, 0, VK_INDEX_TYPE_UINT16); @@ -1199,18 +1200,21 @@ VkDescriptorSet Renderer::createDescriptorFor(const RenderModel& model, const Re if(material.diffuseTexture) { imageInfo.imageView = material.diffuseTexture->view; imageInfo.sampler = material.diffuseTexture->sampler; - - VkWriteDescriptorSet descriptorWrite2 = {}; - descriptorWrite2.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descriptorWrite2.dstSet = set; - descriptorWrite2.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - descriptorWrite2.descriptorCount = 1; - descriptorWrite2.pImageInfo = &imageInfo; - descriptorWrite2.dstBinding = 3; - - writes.push_back(descriptorWrite2); + } else { + imageInfo.imageView = dummyView; + imageInfo.sampler = dummySampler; } + VkWriteDescriptorSet descriptorWrite2 = {}; + descriptorWrite2.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptorWrite2.dstSet = set; + descriptorWrite2.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + descriptorWrite2.descriptorCount = 1; + descriptorWrite2.pImageInfo = &imageInfo; + descriptorWrite2.dstBinding = 3; + + writes.push_back(descriptorWrite2); + VkDescriptorImageInfo normalImageInfo = {}; normalImageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; @@ -1269,3 +1273,128 @@ VkDescriptorSet Renderer::createDescriptorFor(const RenderModel& model, const Re return set; } + +void Renderer::createDummyTexture() { + VkImageCreateInfo imageInfo = {}; + imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + imageInfo.imageType = VK_IMAGE_TYPE_2D; + imageInfo.extent.width = 1; + imageInfo.extent.height = 1; + imageInfo.extent.depth = 1; + imageInfo.mipLevels = 1; + imageInfo.arrayLayers = 1; + imageInfo.format = VK_FORMAT_R8G8B8A8_UNORM; + imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL; + imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + imageInfo.samples = VK_SAMPLE_COUNT_1_BIT; + + vkCreateImage(device, &imageInfo, nullptr, &dummyImage); + + VkMemoryRequirements memRequirements; + vkGetImageMemoryRequirements(device, dummyImage, &memRequirements); + + VkMemoryAllocateInfo allocInfo = {}; + allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + allocInfo.allocationSize = memRequirements.size; + allocInfo.memoryTypeIndex = findMemoryType( + memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + + vkAllocateMemory(device, &allocInfo, nullptr, &dummyMemory); + + vkBindImageMemory(device, dummyImage, dummyMemory, 0); + + // copy image data + VkBuffer stagingBuffer; + VkDeviceMemory stagingBufferMemory; + + VkBufferCreateInfo bufferInfo = {}; + bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + bufferInfo.size = 1; + bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + + vkCreateBuffer(device, &bufferInfo, nullptr, &stagingBuffer); + + // allocate staging memory + vkGetBufferMemoryRequirements(device, stagingBuffer, &memRequirements); + + allocInfo = {}; + allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + allocInfo.allocationSize = memRequirements.size; + allocInfo.memoryTypeIndex = + findMemoryType(memRequirements.memoryTypeBits, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + + vkAllocateMemory(device, &allocInfo, nullptr, &stagingBufferMemory); + + vkBindBufferMemory(device, stagingBuffer, stagingBufferMemory, 0); + + int dummydata[4] = {1, 1, 1, 1}; + + // copy to staging buffer + void* mapped_data; + vkMapMemory(device, stagingBufferMemory, 0, 4, 0, &mapped_data); + memcpy(mapped_data, dummydata, 1); + vkUnmapMemory(device, stagingBufferMemory); + + // copy staging buffer to image + VkCommandBuffer commandBuffer = beginSingleTimeCommands(); + + VkImageSubresourceRange range = {}; + range.baseMipLevel = 0; + range.levelCount = 1; + range.baseArrayLayer = 0; + range.layerCount = 1; + + inlineTransitionImageLayout(commandBuffer, dummyImage, + imageInfo.format, VK_IMAGE_ASPECT_COLOR_BIT, + range, VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + + VkBufferImageCopy region = {}; + region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + region.imageSubresource.mipLevel = 0; + region.imageSubresource.baseArrayLayer = 0; + region.imageSubresource.layerCount = 1; + region.imageExtent = {(uint32_t)1, + (uint32_t)1, 1}; + + vkCmdCopyBufferToImage(commandBuffer, stagingBuffer, dummyImage, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + + inlineTransitionImageLayout(commandBuffer, dummyImage, + imageInfo.format, VK_IMAGE_ASPECT_COLOR_BIT, + range, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + + endSingleTimeCommands(commandBuffer); + + range = {}; + range.levelCount = 1; + range.layerCount = 1; + range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + + VkImageViewCreateInfo viewInfo = {}; + viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + viewInfo.image = dummyImage; + viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; + viewInfo.format = imageInfo.format; + viewInfo.subresourceRange = range; + + vkCreateImageView(device, &viewInfo, nullptr, &dummyView); + + VkSamplerCreateInfo samplerInfo = {}; + samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + samplerInfo.magFilter = VK_FILTER_LINEAR; + samplerInfo.minFilter = VK_FILTER_LINEAR; + samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; + samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; + samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; + samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + samplerInfo.maxLod = 1.0f; + + vkCreateSampler(device, &samplerInfo, nullptr, &dummySampler); +}