From 82ede190a6b556341f98155c3a01af0a88a1ea97 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Thu, 25 Oct 2018 08:40:24 -0400 Subject: [PATCH] Add add_shaders add_data CMake functions --- CMakeLists.txt | 28 ++++++++-------------- cmake/BuildShaders.cmake | 16 +++++++++++++ cmake/CopyData.cmake | 8 +++++++ src/main.cpp | 22 +++++++++--------- src/postpass.cpp | 4 ++-- src/worldpass.cpp | 50 ++++++++++++++++++++-------------------- 6 files changed, 72 insertions(+), 56 deletions(-) create mode 100644 cmake/BuildShaders.cmake create mode 100644 cmake/CopyData.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 4fc96ce..bc0789e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,9 @@ project(Graph) list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) +include(cmake/BuildShaders.cmake) +include(cmake/CopyData.cmake) + set(CMAKE_CXX_STANDARD 14) find_package(SDL2 REQUIRED) @@ -21,22 +24,11 @@ add_executable(Graph target_link_libraries(Graph PUBLIC SDL2::SDL2 SDL2::SDL2main Vulkan::Vulkan assimp::assimp) target_include_directories(Graph PUBLIC include) -macro(compile_shader src) - add_custom_command( - OUTPUT ${src}.spv - COMMAND glslangValidator -V ${CMAKE_CURRENT_SOURCE_DIR}/shaders/${src} -o ${CMAKE_CURRENT_BINARY_DIR}/${src}.spv - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/shaders/${src} - ) +add_shaders(Graph + shaders/triangle.vert + shaders/triangle.frag + shaders/post.vert + shaders/post.frag) - list(APPEND SPV_FILES ${src}.spv) -endmacro() - -compile_shader(triangle.vert) -compile_shader(triangle.frag) -compile_shader(post.vert) -compile_shader(post.frag) - -add_custom_target(BuildShaders DEPENDS ${SPV_FILES}) -add_dependencies(Graph BuildShaders) - -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/data/suzanne.obj ${CMAKE_CURRENT_BINARY_DIR}/suzanne.obj COPYONLY) +add_data(Graph + data/suzanne.obj) diff --git a/cmake/BuildShaders.cmake b/cmake/BuildShaders.cmake new file mode 100644 index 0000000..1a1d04d --- /dev/null +++ b/cmake/BuildShaders.cmake @@ -0,0 +1,16 @@ +function(add_shaders target) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/shaders) + + foreach(src IN LISTS ARGN) + add_custom_command( + OUTPUT ${src}.spv + COMMAND glslangValidator -V ${CMAKE_CURRENT_SOURCE_DIR}/${src} -o ${CMAKE_CURRENT_BINARY_DIR}/${src}.spv + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${src} + ) + + list(APPEND SPV_FILES ${src}.spv) + endforeach() + + add_custom_target(BuildShaders DEPENDS ${SPV_FILES}) + add_dependencies(${target} BuildShaders) +endfunction() diff --git a/cmake/CopyData.cmake b/cmake/CopyData.cmake new file mode 100644 index 0000000..9208364 --- /dev/null +++ b/cmake/CopyData.cmake @@ -0,0 +1,8 @@ +function(add_data target) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/data) + + foreach(data IN LISTS ARGN) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${data} ${CMAKE_CURRENT_BINARY_DIR}/${data} COPYONLY) + endforeach() +endfunction() + diff --git a/src/main.cpp b/src/main.cpp index 70315ce..233a710 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -89,7 +89,7 @@ void writeConfig() { file << "width=" << w << "\n"; file << "height=" << h << "\n"; - + file << "fullscreen=" << windowFullscreen << "\n"; } @@ -105,7 +105,7 @@ int main(int, char*[]) { SDL_WINDOW_RESIZABLE); if(!window) return -1; - + SDL_SetWindowFullscreen(window, windowFullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); Renderer* renderer = new Renderer(); @@ -116,7 +116,7 @@ int main(int, char*[]) { RenderTarget* target = renderer->createSurfaceRenderTarget(surface); Assimp::Importer importer; - const aiScene* scene = importer.ReadFile("suzanne.obj", aiProcess_Triangulate); + const aiScene* scene = importer.ReadFile("data/suzanne.obj", aiProcess_Triangulate); aiMesh* m = scene->mMeshes[0]; Mesh* mesh = new Mesh(); @@ -139,10 +139,10 @@ int main(int, char*[]) { World world; world.meshes.push_back(mesh); - + Light* light = new Light(); light->position.y = 5; - + world.lights.push_back(light); bool running = true; @@ -156,7 +156,7 @@ int main(int, char*[]) { if(event.window.event == SDL_WINDOWEVENT_RESIZED) target = renderer->createSurfaceRenderTarget(surface, target); } - + if(event.type == SDL_KEYDOWN && event.key.keysym.scancode == SDL_SCANCODE_F11) { if(windowFullscreen == 1) { SDL_SetWindowFullscreen(window, 0); @@ -165,10 +165,10 @@ int main(int, char*[]) { SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); windowFullscreen = 1; } - + target = renderer->createSurfaceRenderTarget(surface, target); } - + if(event.type == SDL_KEYDOWN && event.key.keysym.scancode == SDL_SCANCODE_F12) { renderer->takeScreenshot(target); } @@ -176,13 +176,13 @@ int main(int, char*[]) { renderer->render(world, target); } - + delete light; renderer->destroyMeshBuffers(mesh); - + delete mesh; - + renderer->destroyRenderTarget(target); vkDestroySurfaceKHR(renderer->getInstance(), surface, nullptr); diff --git a/src/postpass.cpp b/src/postpass.cpp index 010125d..3b0be89 100644 --- a/src/postpass.cpp +++ b/src/postpass.cpp @@ -75,8 +75,8 @@ void PostPass::createDescriptorSetLayout() { } void PostPass::createPipeline() { - VkShaderModule vertShaderModule = renderer_.createShader("post.vert.spv"); - VkShaderModule fragShaderModule = renderer_.createShader("post.frag.spv"); + VkShaderModule vertShaderModule = renderer_.createShader("shaders/post.vert.spv"); + VkShaderModule fragShaderModule = renderer_.createShader("shaders/post.frag.spv"); VkPipelineShaderStageCreateInfo vertShaderStageInfo = {}; vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; diff --git a/src/worldpass.cpp b/src/worldpass.cpp index bb2718d..c83dd6e 100644 --- a/src/worldpass.cpp +++ b/src/worldpass.cpp @@ -19,11 +19,11 @@ WorldPass::WorldPass(Renderer& renderer) : renderer_(renderer) { WorldPass::~WorldPass() { vkDestroyRenderPass(renderer_.getDevice(), renderPass_, nullptr); - vkDestroyDescriptorSetLayout(renderer_.getDevice(), setLayout_, nullptr); + vkDestroyDescriptorSetLayout(renderer_.getDevice(), setLayout_, nullptr); vkDestroyPipeline(renderer_.getDevice(), pipeline_, nullptr); vkDestroyPipelineLayout(renderer_.getDevice(), pipelineLayout_, nullptr); - + vkFreeMemory(renderer_.getDevice(), lightMemory_, nullptr); vkDestroyBuffer(renderer_.getDevice(), lightBuffer_, nullptr); } @@ -33,19 +33,19 @@ void WorldPass::render(VkCommandBuffer commandBuffer, World& world, RenderTarget glm::vec4 position; glm::vec3 color; }; - + ShaderLight* data; vkMapMemory(renderer_.getDevice(), lightMemory_, 0, sizeof(float) * (4 + 3) * 32, 0, (void**)&data); - + for(size_t i = 0; i < world.lights.size(); i++) { data->position = glm::vec4(world.lights[i]->position, 0.0); data->color = world.lights[i]->color; - + data++; } - + vkUnmapMemory(renderer_.getDevice(), lightMemory_); - + std::array clearColor = {}; clearColor[1].depthStencil.depth = 1.0f; @@ -61,7 +61,7 @@ void WorldPass::render(VkCommandBuffer commandBuffer, World& world, RenderTarget vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_); vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout_, 0, 1, &descriptorSet_, 0, nullptr); - + for(const auto& mesh : world.meshes) { glm::mat4 mvp; mvp = glm::perspective(glm::radians(75.0f), (float)target->extent.width / target->extent.height, 0.1f, 100.0f); @@ -89,7 +89,7 @@ void WorldPass::createRenderPass() { colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; colorAttachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - + VkAttachmentDescription depthAttachment = {}; depthAttachment.format = VK_FORMAT_D32_SFLOAT; depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT; @@ -106,13 +106,13 @@ void WorldPass::createRenderPass() { VkAttachmentReference depthAttachmentRef = {}; depthAttachmentRef.attachment = 1; depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - + VkSubpassDescription subpass = {}; subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; subpass.colorAttachmentCount = 1; subpass.pColorAttachments = &colorAttachmentRef; subpass.pDepthStencilAttachment = &depthAttachmentRef; - + const std::array attachments = { colorAttachment, depthAttachment @@ -133,18 +133,18 @@ void WorldPass::createDescriptorSetLayout() { lightBufferBinding.descriptorCount = 1; lightBufferBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; lightBufferBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - + VkDescriptorSetLayoutCreateInfo createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; createInfo.bindingCount = 1; createInfo.pBindings = &lightBufferBinding; - + vkCreateDescriptorSetLayout(renderer_.getDevice(), &createInfo, nullptr, &setLayout_); } void WorldPass::createPipeline() { - VkShaderModule vertShaderModule = renderer_.createShader("triangle.vert.spv"); - VkShaderModule fragShaderModule = renderer_.createShader("triangle.frag.spv"); + VkShaderModule vertShaderModule = renderer_.createShader("shaders/triangle.vert.spv"); + VkShaderModule fragShaderModule = renderer_.createShader("shaders/triangle.frag.spv"); VkPipelineShaderStageCreateInfo vertShaderStageInfo = {}; vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; @@ -212,7 +212,7 @@ void WorldPass::createPipeline() { depthState.depthTestEnable = true; depthState.depthWriteEnable = true; depthState.depthCompareOp = VK_COMPARE_OP_LESS; - + VkPipelineColorBlendStateCreateInfo colorBlending = {}; colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; colorBlending.attachmentCount = 1; @@ -268,17 +268,17 @@ void WorldPass::createUniformBuffer() { bufferInfo.size = sizeof(float) * (4 + 3) * 32; bufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - + vkCreateBuffer(renderer_.getDevice(), &bufferInfo, nullptr, &lightBuffer_); - + VkMemoryRequirements memRequirements; vkGetBufferMemoryRequirements(renderer_.getDevice(), lightBuffer_, &memRequirements); - + VkMemoryAllocateInfo allocInfo = {}; allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; allocInfo.allocationSize = memRequirements.size; allocInfo.memoryTypeIndex = renderer_.findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); - + vkAllocateMemory(renderer_.getDevice(), &allocInfo, nullptr, &lightMemory_); vkBindBufferMemory(renderer_.getDevice(), lightBuffer_, lightMemory_, 0); } @@ -291,23 +291,23 @@ void WorldPass::createDescriptorSet() { allocInfo.pSetLayouts = &setLayout_; vkAllocateDescriptorSets(renderer_.getDevice(), &allocInfo, &descriptorSet_); - + VkDescriptorBufferInfo bufferInfo = {}; bufferInfo.buffer = lightBuffer_; bufferInfo.range = sizeof(float) * (4 + 3) * 32; - + VkWriteDescriptorSet descriptorWrite = {}; descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descriptorWrite.descriptorCount = 1; descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; descriptorWrite.dstSet = descriptorSet_; descriptorWrite.pBufferInfo = &bufferInfo; - + vkUpdateDescriptorSets(renderer_.getDevice(), 1, &descriptorWrite, 0, nullptr); - + float* data; vkMapMemory(renderer_.getDevice(), lightMemory_, 0, sizeof(float) * (4 + 3) * 32, 0, (void**)&data); - + for(uint32_t i = 0; i < (4 + 3) * 32; i++) data[i] = 0.0f;