From 3b37257a9e783a90da98a000ca43b64521ec2f85 Mon Sep 17 00:00:00 2001 From: Alexander Gauggel <agauggel@uni-koblenz.de> Date: Sat, 3 Jul 2021 10:57:27 +0200 Subject: [PATCH] [#87] Setup mesh shader project --- projects/CMakeLists.txt | 3 +- projects/mesh_shader/.gitignore | 1 + projects/mesh_shader/CMakeLists.txt | 28 ++++ .../mesh_shader/resources/shaders/shader.frag | 9 ++ .../mesh_shader/resources/shaders/shader.vert | 25 ++++ projects/mesh_shader/src/main.cpp | 137 ++++++++++++++++++ 6 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 projects/mesh_shader/.gitignore create mode 100644 projects/mesh_shader/CMakeLists.txt create mode 100644 projects/mesh_shader/resources/shaders/shader.frag create mode 100644 projects/mesh_shader/resources/shaders/shader.vert create mode 100644 projects/mesh_shader/src/main.cpp diff --git a/projects/CMakeLists.txt b/projects/CMakeLists.txt index 34fbcb0c..8f9dbbec 100644 --- a/projects/CMakeLists.txt +++ b/projects/CMakeLists.txt @@ -4,4 +4,5 @@ add_subdirectory(bloom) add_subdirectory(first_triangle) add_subdirectory(first_mesh) add_subdirectory(first_scene) -add_subdirectory(voxelization) \ No newline at end of file +add_subdirectory(voxelization) +add_subdirectory(mesh_shader) \ No newline at end of file diff --git a/projects/mesh_shader/.gitignore b/projects/mesh_shader/.gitignore new file mode 100644 index 00000000..7e24fd7b --- /dev/null +++ b/projects/mesh_shader/.gitignore @@ -0,0 +1 @@ +first_triangle \ No newline at end of file diff --git a/projects/mesh_shader/CMakeLists.txt b/projects/mesh_shader/CMakeLists.txt new file mode 100644 index 00000000..0b2847cd --- /dev/null +++ b/projects/mesh_shader/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.16) +project(mesh_shader) + +# setting c++ standard for the project +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# this should fix the execution path to load local files from the project +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +# adding source files to the project +add_executable(mesh_shader src/main.cpp) + +# this should fix the execution path to load local files from the project (for MSVC) +if(MSVC) + set_target_properties(mesh_shader PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) + set_target_properties(mesh_shader PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) + + # in addition to setting the output directory, the working directory has to be set + # by default visual studio sets the working directory to the build directory, when using the debugger + set_target_properties(mesh_shader PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) +endif() + +# including headers of dependencies and the VkCV framework +target_include_directories(mesh_shader SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_testing_include} ${vkcv_camera_include} ${vkcv_shader_compiler_include} ${vkcv_gui_include}) + +# linking with libraries from all dependencies and the VkCV framework +target_link_libraries(mesh_shader vkcv vkcv_testing vkcv_camera vkcv_shader_compiler vkcv_gui) diff --git a/projects/mesh_shader/resources/shaders/shader.frag b/projects/mesh_shader/resources/shaders/shader.frag new file mode 100644 index 00000000..080678be --- /dev/null +++ b/projects/mesh_shader/resources/shaders/shader.frag @@ -0,0 +1,9 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +layout(location = 0) in vec3 fragColor; +layout(location = 0) out vec4 outColor; + +void main() { + outColor = vec4(fragColor, 1.0); +} \ No newline at end of file diff --git a/projects/mesh_shader/resources/shaders/shader.vert b/projects/mesh_shader/resources/shaders/shader.vert new file mode 100644 index 00000000..e129186a --- /dev/null +++ b/projects/mesh_shader/resources/shaders/shader.vert @@ -0,0 +1,25 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +layout(location = 0) out vec3 fragColor; + +layout( push_constant ) uniform constants{ + mat4 mvp; +}; + +void main() { + vec3 positions[3] = { + vec3(-0.5, 0.5, -1), + vec3( 0.5, 0.5, -1), + vec3(0, -0.5, -1) + }; + + vec3 colors[3] = { + vec3(1, 0, 0), + vec3(0, 1, 0), + vec3(0, 0, 1) + }; + + gl_Position = mvp * vec4(positions[gl_VertexIndex], 1.0); + fragColor = colors[gl_VertexIndex]; +} \ No newline at end of file diff --git a/projects/mesh_shader/src/main.cpp b/projects/mesh_shader/src/main.cpp new file mode 100644 index 00000000..925a6308 --- /dev/null +++ b/projects/mesh_shader/src/main.cpp @@ -0,0 +1,137 @@ +#include <iostream> +#include <vkcv/Core.hpp> +#include <GLFW/glfw3.h> +#include <vkcv/camera/CameraManager.hpp> +#include <chrono> + +#include <vkcv/shader/GLSLCompiler.hpp> +#include <vkcv/gui/GUI.hpp> + +int main(int argc, const char** argv) { + const char* applicationName = "Mesh shader"; + + const int windowWidth = 1280; + const int windowHeight = 720; + vkcv::Window window = vkcv::Window::create( + applicationName, + windowWidth, + windowHeight, + false + ); + + vkcv::Core core = vkcv::Core::create( + window, + applicationName, + VK_MAKE_VERSION(0, 0, 1), + { vk::QueueFlagBits::eTransfer,vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute }, + {}, + { "VK_KHR_swapchain" } + ); + + vkcv::gui::GUI gui (core, window); + + const auto& context = core.getContext(); + const vk::Instance& instance = context.getInstance(); + const vk::PhysicalDevice& physicalDevice = context.getPhysicalDevice(); + const vk::Device& device = context.getDevice(); + + const vkcv::AttachmentDescription present_color_attachment( + vkcv::AttachmentOperation::STORE, + vkcv::AttachmentOperation::CLEAR, + core.getSwapchain().getFormat()); + + vkcv::PassConfig trianglePassDefinition({ present_color_attachment }); + vkcv::PassHandle trianglePass = core.createPass(trianglePassDefinition); + + if (!trianglePass) + { + std::cout << "Error. Could not create renderpass. Exiting." << std::endl; + return EXIT_FAILURE; + } + + vkcv::ShaderProgram triangleShaderProgram{}; + vkcv::shader::GLSLCompiler compiler; + + compiler.compile(vkcv::ShaderStage::VERTEX, std::filesystem::path("resources/shaders/shader.vert"), + [&triangleShaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { + triangleShaderProgram.addShader(shaderStage, path); + }); + + compiler.compile(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("resources/shaders/shader.frag"), + [&triangleShaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { + triangleShaderProgram.addShader(shaderStage, path); + }); + + const vkcv::PipelineConfig trianglePipelineDefinition { + triangleShaderProgram, + (uint32_t)windowWidth, + (uint32_t)windowHeight, + trianglePass, + {}, + {}, + false + }; + + vkcv::PipelineHandle trianglePipeline = core.createGraphicsPipeline(trianglePipelineDefinition); + + if (!trianglePipeline) + { + std::cout << "Error. Could not create graphics pipeline. Exiting." << std::endl; + return EXIT_FAILURE; + } + + auto start = std::chrono::system_clock::now(); + + vkcv::ImageHandle swapchainImageHandle = vkcv::ImageHandle::createSwapchainImageHandle(); + + const vkcv::Mesh renderMesh({}, nullptr, 3); + vkcv::DrawcallInfo drawcall(renderMesh, {}); + + const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); + + vkcv::camera::CameraManager cameraManager(window); + uint32_t camIndex0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); + + cameraManager.getCamera(camIndex0).setPosition(glm::vec3(0, 0, -2)); + + while (window.isWindowOpen()) + { + window.pollEvents(); + + uint32_t swapchainWidth, swapchainHeight; // No resizing = No problem + if (!core.beginFrame(swapchainWidth, swapchainHeight)) { + continue; + } + + auto end = std::chrono::system_clock::now(); + auto deltatime = std::chrono::duration_cast<std::chrono::microseconds>(end - start); + start = end; + + cameraManager.update(0.000001 * static_cast<double>(deltatime.count())); + glm::mat4 mvp = cameraManager.getActiveCamera().getMVP(); + + vkcv::PushConstantData pushConstantData((void*)&mvp, sizeof(glm::mat4)); + auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); + + core.recordDrawcallsToCmdStream( + cmdStream, + trianglePass, + trianglePipeline, + pushConstantData, + { drawcall }, + { swapchainInput }); + + core.prepareSwapchainImageForPresent(cmdStream); + core.submitCommandStream(cmdStream); + + // gui.beginGUI(); + // + // ImGui::Begin("Settings"); + // ImGui::End(); + // + // gui.endGUI(); + + core.endFrame(); + } + return 0; +} -- GitLab