diff --git a/projects/CMakeLists.txt b/projects/CMakeLists.txt index c4fde45438e5c8446c6a1d50ceec16f830e8ebfd..8af45df24a4f0541144952a2d326abd6e041ab8d 100644 --- a/projects/CMakeLists.txt +++ b/projects/CMakeLists.txt @@ -6,3 +6,5 @@ add_subdirectory(first_scene) add_subdirectory(particle_simulation) add_subdirectory(voxelization) add_subdirectory(mesh_shader) +add_subdirectory(draw_indirect) +add_subdirectory(bindless_textures) diff --git a/projects/bindless_textures/.gitignore b/projects/bindless_textures/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..cd45650aee8ab49ad568556452dde2d9d51d5f13 --- /dev/null +++ b/projects/bindless_textures/.gitignore @@ -0,0 +1 @@ +bindless_textures \ No newline at end of file diff --git a/projects/bindless_textures/CMakeLists.txt b/projects/bindless_textures/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..08cc636af2495afa3bb69cc7b652cc20eb4fa117 --- /dev/null +++ b/projects/bindless_textures/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.16) +project(bindless_textures) + +# 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(bindless_textures src/main.cpp) + +# this should fix the execution path to load local files from the project (for MSVC) +if(MSVC) + set_target_properties(bindless_textures PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) + set_target_properties(bindless_textures 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(bindless_textures PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) +endif() + +# including headers of dependencies and the VkCV framework +target_include_directories(bindless_textures SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_asset_loader_include} ${vkcv_camera_include} ${vkcv_shader_compiler_include}) + +# linking with libraries from all dependencies and the VkCV framework +target_link_libraries(bindless_textures vkcv ${vkcv_libraries} vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv_camera vkcv_shader_compiler) diff --git a/projects/bindless_textures/resources/Szene/Szene.bin b/projects/bindless_textures/resources/Szene/Szene.bin new file mode 100644 index 0000000000000000000000000000000000000000..c87d27637516b0bbf864251dd162773f5cc53e06 --- /dev/null +++ b/projects/bindless_textures/resources/Szene/Szene.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ee4742718f720d589a2a03f5d879f8c50ba9057718d191a43b046eaa9071080d +size 70328 diff --git a/projects/bindless_textures/resources/Szene/Szene.gltf b/projects/bindless_textures/resources/Szene/Szene.gltf new file mode 100644 index 0000000000000000000000000000000000000000..e5a32b29af5d0a2ac5f497e60b4b92c1873e1df9 --- /dev/null +++ b/projects/bindless_textures/resources/Szene/Szene.gltf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:75ba834118792ebbacf528a1690c7d04df4b4c8122b9f99a9aa9a9d075d2c86a +size 7421 diff --git a/projects/bindless_textures/resources/Szene/boards2_vcyc.jpg b/projects/bindless_textures/resources/Szene/boards2_vcyc.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2636039e272289c0fba3fa2d88a060b857501248 --- /dev/null +++ b/projects/bindless_textures/resources/Szene/boards2_vcyc.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cca33a6e58ddd1b37a6e6853a9aa0e7b15ca678937119194752393dd2a0a0564 +size 1192476 diff --git a/projects/bindless_textures/resources/Szene/boards2_vcyc_jpg.jpg b/projects/bindless_textures/resources/Szene/boards2_vcyc_jpg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2636039e272289c0fba3fa2d88a060b857501248 --- /dev/null +++ b/projects/bindless_textures/resources/Szene/boards2_vcyc_jpg.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cca33a6e58ddd1b37a6e6853a9aa0e7b15ca678937119194752393dd2a0a0564 +size 1192476 diff --git a/projects/bindless_textures/resources/cube/boards2_vcyc_jpg.jpg b/projects/bindless_textures/resources/cube/boards2_vcyc_jpg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2636039e272289c0fba3fa2d88a060b857501248 --- /dev/null +++ b/projects/bindless_textures/resources/cube/boards2_vcyc_jpg.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cca33a6e58ddd1b37a6e6853a9aa0e7b15ca678937119194752393dd2a0a0564 +size 1192476 diff --git a/projects/bindless_textures/resources/cube/cube.bin b/projects/bindless_textures/resources/cube/cube.bin new file mode 100644 index 0000000000000000000000000000000000000000..3303cd8635848bee18e10ab8754d5e4e7218db92 --- /dev/null +++ b/projects/bindless_textures/resources/cube/cube.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9bb9b6b8bbe50a0aaa517057f245ee844f80afa7426dacb2aed4128f71629ce4 +size 840 diff --git a/projects/bindless_textures/resources/cube/cube.blend b/projects/bindless_textures/resources/cube/cube.blend new file mode 100644 index 0000000000000000000000000000000000000000..62ccb2c742094bcfb5ed194ab905bffae86bfd65 --- /dev/null +++ b/projects/bindless_textures/resources/cube/cube.blend @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6c1e245f259c610528c9485db6688928faac0ab2addee9e3c2dde7740e4dd09 +size 774920 diff --git a/projects/bindless_textures/resources/cube/cube.blend1 b/projects/bindless_textures/resources/cube/cube.blend1 new file mode 100644 index 0000000000000000000000000000000000000000..13f21dcca218d7bc7a07a8a9682b5e1d9e607736 --- /dev/null +++ b/projects/bindless_textures/resources/cube/cube.blend1 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4496f423569b8ca81f3b3a55fad00f925557e0193fb9dbe6cdce7e71fb48f7b +size 774920 diff --git a/projects/bindless_textures/resources/cube/cube.glb b/projects/bindless_textures/resources/cube/cube.glb new file mode 100644 index 0000000000000000000000000000000000000000..66a42c65e71dcf375e04cc378256024dd3c7834d --- /dev/null +++ b/projects/bindless_textures/resources/cube/cube.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:198568b715f397d78f7c358c0f709a419e7fd677e54cdec7c19f71b5ed264897 +size 1194508 diff --git a/projects/bindless_textures/resources/cube/cube.gltf b/projects/bindless_textures/resources/cube/cube.gltf new file mode 100644 index 0000000000000000000000000000000000000000..428176144843dd06c78fe1d11a6392a0ea02b22d --- /dev/null +++ b/projects/bindless_textures/resources/cube/cube.gltf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f82f455647a84ca6242882ae26a79a499d3ce594f8de317ab89488c5b79721ac +size 2823 diff --git a/projects/bindless_textures/resources/shaders/shader.frag b/projects/bindless_textures/resources/shaders/shader.frag new file mode 100644 index 0000000000000000000000000000000000000000..71a1de69c57c0d7b7d4665095410e7acaf8dbd62 --- /dev/null +++ b/projects/bindless_textures/resources/shaders/shader.frag @@ -0,0 +1,14 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +layout(location = 0) in vec3 passNormal; +layout(location = 1) in vec2 passUV; + +layout(location = 0) out vec3 outColor; + +layout(set=0, binding=0) uniform texture2D meshTexture; +layout(set=0, binding=1) uniform sampler textureSampler; + +void main() { + outColor = texture(sampler2D(meshTexture, textureSampler), passUV).rgb; +} \ No newline at end of file diff --git a/projects/bindless_textures/resources/shaders/shader.vert b/projects/bindless_textures/resources/shaders/shader.vert new file mode 100644 index 0000000000000000000000000000000000000000..76855152253b48b7400f016d063ed4f0e507435e --- /dev/null +++ b/projects/bindless_textures/resources/shaders/shader.vert @@ -0,0 +1,19 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +layout(location = 0) in vec3 inPosition; +layout(location = 1) in vec3 inNormal; +layout(location = 2) in vec2 inUV; + +layout(location = 0) out vec3 passNormal; +layout(location = 1) out vec2 passUV; + +layout( push_constant ) uniform constants{ + mat4 mvp; +}; + +void main() { + gl_Position = mvp * vec4(inPosition, 1.0); + passNormal = inNormal; + passUV = inUV; +} \ No newline at end of file diff --git a/projects/bindless_textures/resources/triangle/Triangle.bin b/projects/bindless_textures/resources/triangle/Triangle.bin new file mode 100644 index 0000000000000000000000000000000000000000..57f26ad96592b64377e6aa93823d96a94e6c5022 --- /dev/null +++ b/projects/bindless_textures/resources/triangle/Triangle.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:412ebd5f7242c266b4957e7e26be13aa331dbcb7bbb854ab334a2437ae8ed959 +size 104 diff --git a/projects/bindless_textures/resources/triangle/Triangle.blend b/projects/bindless_textures/resources/triangle/Triangle.blend new file mode 100644 index 0000000000000000000000000000000000000000..2421dc5e1bb029d73a9ec09cc4530c5196851fd7 --- /dev/null +++ b/projects/bindless_textures/resources/triangle/Triangle.blend @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:387e544df173219fbf292a64a6656d1d782bbf71a5a9e9fdef0a308f47b05477 +size 758144 diff --git a/projects/bindless_textures/resources/triangle/Triangle.glb b/projects/bindless_textures/resources/triangle/Triangle.glb new file mode 100644 index 0000000000000000000000000000000000000000..4148620cd6af0dadbc791aa1c52bb5431a40884b --- /dev/null +++ b/projects/bindless_textures/resources/triangle/Triangle.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4be087a605212d139416b5352a018283b26b99260cbcddb7013a1beeb331227 +size 980 diff --git a/projects/bindless_textures/resources/triangle/Triangle.gltf b/projects/bindless_textures/resources/triangle/Triangle.gltf new file mode 100644 index 0000000000000000000000000000000000000000..a188e6ee16a5e8486cf307c7bda8cfd99bdbeea6 --- /dev/null +++ b/projects/bindless_textures/resources/triangle/Triangle.gltf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5fc354e040f79cff329e919677b194c75e3a522c6406f75c1108ad9575f12ec +size 2202 diff --git a/projects/bindless_textures/src/main.cpp b/projects/bindless_textures/src/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..731d3e56975ff0cd2d8e6d503a19d56de1b922fe --- /dev/null +++ b/projects/bindless_textures/src/main.cpp @@ -0,0 +1,219 @@ +#include <iostream> +#include <vkcv/Core.hpp> +#include <GLFW/glfw3.h> +#include <vkcv/camera/CameraManager.hpp> +#include <chrono> +#include <vkcv/asset/asset_loader.hpp> +#include <vkcv/shader/GLSLCompiler.hpp> + +int main(int argc, const char** argv) { + const char* applicationName = "First Mesh"; + + uint32_t windowWidth = 800; + uint32_t windowHeight = 600; + + vkcv::Window window = vkcv::Window::create( + applicationName, + windowWidth, + windowHeight, + true + ); + + vkcv::Core core = vkcv::Core::create( + window, + applicationName, + VK_MAKE_VERSION(0, 0, 1), + { vk::QueueFlagBits::eGraphics ,vk::QueueFlagBits::eCompute , vk::QueueFlagBits::eTransfer }, + {}, + { "VK_KHR_swapchain" } + ); + + vkcv::asset::Scene mesh; + + const char* path = argc > 1 ? argv[1] : "resources/cube/cube.gltf"; + int result = vkcv::asset::loadScene(path, mesh); + + if (result == 1) { + std::cout << "Mesh loading successful!" << std::endl; + } else { + std::cerr << "Mesh loading failed: " << result << std::endl; + return 1; + } + + assert(!mesh.vertexGroups.empty()); + auto vertexBuffer = core.createBuffer<uint8_t>( + vkcv::BufferType::VERTEX, + mesh.vertexGroups[0].vertexBuffer.data.size(), + vkcv::BufferMemoryType::DEVICE_LOCAL + ); + + vertexBuffer.fill(mesh.vertexGroups[0].vertexBuffer.data); + + auto indexBuffer = core.createBuffer<uint8_t>( + vkcv::BufferType::INDEX, + mesh.vertexGroups[0].indexBuffer.data.size(), + vkcv::BufferMemoryType::DEVICE_LOCAL + ); + + indexBuffer.fill(mesh.vertexGroups[0].indexBuffer.data); + + // an example attachment for passes that output to the window + const vkcv::AttachmentDescription present_color_attachment( + vkcv::AttachmentOperation::STORE, + vkcv::AttachmentOperation::CLEAR, + core.getSwapchain().getFormat() + ); + + const vkcv::AttachmentDescription depth_attachment( + vkcv::AttachmentOperation::STORE, + vkcv::AttachmentOperation::CLEAR, + vk::Format::eD32Sfloat + ); + + vkcv::PassConfig firstMeshPassDefinition({ present_color_attachment, depth_attachment }); + vkcv::PassHandle firstMeshPass = core.createPass(firstMeshPassDefinition); + + if (!firstMeshPass) { + std::cerr << "Error. Could not create renderpass. Exiting." << std::endl; + return EXIT_FAILURE; + } + + vkcv::ShaderProgram firstMeshProgram; + vkcv::shader::GLSLCompiler compiler; + + compiler.compile(vkcv::ShaderStage::VERTEX, std::filesystem::path("resources/shaders/shader.vert"), + [&firstMeshProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { + firstMeshProgram.addShader(shaderStage, path); + }); + + compiler.compile(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("resources/shaders/shader.frag"), + [&firstMeshProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { + firstMeshProgram.addShader(shaderStage, path); + }); + + auto& attributes = mesh.vertexGroups[0].vertexBuffer.attributes; + + + std::sort(attributes.begin(), attributes.end(), [](const vkcv::asset::VertexAttribute& x, const vkcv::asset::VertexAttribute& y) { + return static_cast<uint32_t>(x.type) < static_cast<uint32_t>(y.type); + }); + + const std::vector<vkcv::VertexAttachment> vertexAttachments = firstMeshProgram.getVertexAttachments(); + std::vector<vkcv::VertexBinding> bindings; + for (size_t i = 0; i < vertexAttachments.size(); i++) { + bindings.push_back(vkcv::VertexBinding(i, { vertexAttachments[i] })); + } + + const vkcv::VertexLayout firstMeshLayout (bindings); + + uint32_t setID = 0; + std::vector<vkcv::DescriptorBinding> descriptorBindings = { firstMeshProgram.getReflectedDescriptors()[setID] }; + vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorBindings); + + const vkcv::PipelineConfig firstMeshPipelineConfig { + firstMeshProgram, + UINT32_MAX, + UINT32_MAX, + firstMeshPass, + {firstMeshLayout}, + { core.getDescriptorSet(descriptorSet).layout }, + true + }; + vkcv::PipelineHandle firstMeshPipeline = core.createGraphicsPipeline(firstMeshPipelineConfig); + + if (!firstMeshPipeline) { + std::cerr << "Error. Could not create graphics pipeline. Exiting." << std::endl; + return EXIT_FAILURE; + } + + if (mesh.textures.empty()) { + std::cerr << "Error. No textures found. Exiting." << std::endl; + return EXIT_FAILURE; + } + + vkcv::asset::Texture &tex = mesh.textures[0]; + vkcv::Image texture = core.createImage(vk::Format::eR8G8B8A8Srgb, tex.w, tex.h); + texture.fill(tex.data.data()); + texture.generateMipChainImmediate(); + texture.switchLayout(vk::ImageLayout::eShaderReadOnlyOptimal); + + vkcv::SamplerHandle sampler = core.createSampler( + vkcv::SamplerFilterType::LINEAR, + vkcv::SamplerFilterType::LINEAR, + vkcv::SamplerMipmapMode::LINEAR, + vkcv::SamplerAddressMode::REPEAT + ); + + const std::vector<vkcv::VertexBufferBinding> vertexBufferBindings = { + vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[0].offset), vertexBuffer.getVulkanHandle()), + vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[1].offset), vertexBuffer.getVulkanHandle()), + vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[2].offset), vertexBuffer.getVulkanHandle()) }; + + vkcv::DescriptorWrites setWrites; + setWrites.sampledImageWrites = { vkcv::SampledImageDescriptorWrite(0, texture.getHandle()) }; + setWrites.samplerWrites = { vkcv::SamplerDescriptorWrite(1, sampler) }; + + core.writeDescriptorSet(descriptorSet, setWrites); + + vkcv::ImageHandle depthBuffer = core.createImage(vk::Format::eD32Sfloat, windowWidth, windowHeight, 1, false).getHandle(); + + const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); + + const vkcv::Mesh renderMesh(vertexBufferBindings, indexBuffer.getVulkanHandle(), mesh.vertexGroups[0].numIndices); + + vkcv::DescriptorSetUsage descriptorUsage(0, core.getDescriptorSet(descriptorSet).vulkanHandle); + vkcv::DrawcallInfo drawcall(renderMesh, { descriptorUsage },1); + + vkcv::camera::CameraManager cameraManager(window); + uint32_t camIndex0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); + uint32_t camIndex1 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL); + + cameraManager.getCamera(camIndex0).setPosition(glm::vec3(0, 0, -3)); + + auto start = std::chrono::system_clock::now(); + + while (window.isWindowOpen()) { + vkcv::Window::pollEvents(); + + if(window.getHeight() == 0 || window.getWidth() == 0) + continue; + + uint32_t swapchainWidth, swapchainHeight; + if (!core.beginFrame(swapchainWidth, swapchainHeight)) { + continue; + } + + if ((swapchainWidth != windowWidth) || ((swapchainHeight != windowHeight))) { + depthBuffer = core.createImage(vk::Format::eD32Sfloat, swapchainWidth, swapchainHeight).getHandle(); + + windowWidth = swapchainWidth; + windowHeight = swapchainHeight; + } + + 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::PushConstants pushConstants (sizeof(glm::mat4)); + pushConstants.appendDrawcall(mvp); + + const std::vector<vkcv::ImageHandle> renderTargets = { swapchainInput, depthBuffer }; + auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); + + core.recordDrawcallsToCmdStream( + cmdStream, + firstMeshPass, + firstMeshPipeline, + pushConstants, + { drawcall }, + renderTargets); + core.prepareSwapchainImageForPresent(cmdStream); + core.submitCommandStream(cmdStream); + core.endFrame(); + } + + return 0; +} diff --git a/projects/draw_indirect/.gitignore b/projects/draw_indirect/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..071dd05c8a5ba569a5a5676358e67166f94790ff --- /dev/null +++ b/projects/draw_indirect/.gitignore @@ -0,0 +1 @@ +draw_indirect \ No newline at end of file diff --git a/projects/draw_indirect/CMakeLists.txt b/projects/draw_indirect/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..01f95ccbcfb40cffc96d6d8272494f695192cced --- /dev/null +++ b/projects/draw_indirect/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.16) +project(draw_indirect) + +# 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(draw_indirect src/main.cpp) + +# this should fix the execution path to load local files from the project (for MSVC) +if(MSVC) + set_target_properties(draw_indirect PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) + set_target_properties(draw_indirect 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(draw_indirect PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) +endif() + +# including headers of dependencies and the VkCV framework +target_include_directories(draw_indirect SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_asset_loader_include} ${vkcv_camera_include} ${vkcv_shader_compiler_include}) + +# linking with libraries from all dependencies and the VkCV framework +target_link_libraries(draw_indirect vkcv ${vkcv_libraries} vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv_camera vkcv_shader_compiler) diff --git a/projects/draw_indirect/resources/Szene/Szene.bin b/projects/draw_indirect/resources/Szene/Szene.bin new file mode 100644 index 0000000000000000000000000000000000000000..c87d27637516b0bbf864251dd162773f5cc53e06 --- /dev/null +++ b/projects/draw_indirect/resources/Szene/Szene.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ee4742718f720d589a2a03f5d879f8c50ba9057718d191a43b046eaa9071080d +size 70328 diff --git a/projects/draw_indirect/resources/Szene/Szene.gltf b/projects/draw_indirect/resources/Szene/Szene.gltf new file mode 100644 index 0000000000000000000000000000000000000000..e5a32b29af5d0a2ac5f497e60b4b92c1873e1df9 --- /dev/null +++ b/projects/draw_indirect/resources/Szene/Szene.gltf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:75ba834118792ebbacf528a1690c7d04df4b4c8122b9f99a9aa9a9d075d2c86a +size 7421 diff --git a/projects/draw_indirect/resources/Szene/boards2_vcyc.jpg b/projects/draw_indirect/resources/Szene/boards2_vcyc.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2636039e272289c0fba3fa2d88a060b857501248 --- /dev/null +++ b/projects/draw_indirect/resources/Szene/boards2_vcyc.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cca33a6e58ddd1b37a6e6853a9aa0e7b15ca678937119194752393dd2a0a0564 +size 1192476 diff --git a/projects/draw_indirect/resources/Szene/boards2_vcyc_jpg.jpg b/projects/draw_indirect/resources/Szene/boards2_vcyc_jpg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2636039e272289c0fba3fa2d88a060b857501248 --- /dev/null +++ b/projects/draw_indirect/resources/Szene/boards2_vcyc_jpg.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cca33a6e58ddd1b37a6e6853a9aa0e7b15ca678937119194752393dd2a0a0564 +size 1192476 diff --git a/projects/draw_indirect/resources/cube/boards2_vcyc_jpg.jpg b/projects/draw_indirect/resources/cube/boards2_vcyc_jpg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2636039e272289c0fba3fa2d88a060b857501248 --- /dev/null +++ b/projects/draw_indirect/resources/cube/boards2_vcyc_jpg.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cca33a6e58ddd1b37a6e6853a9aa0e7b15ca678937119194752393dd2a0a0564 +size 1192476 diff --git a/projects/draw_indirect/resources/cube/cube.bin b/projects/draw_indirect/resources/cube/cube.bin new file mode 100644 index 0000000000000000000000000000000000000000..3303cd8635848bee18e10ab8754d5e4e7218db92 --- /dev/null +++ b/projects/draw_indirect/resources/cube/cube.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9bb9b6b8bbe50a0aaa517057f245ee844f80afa7426dacb2aed4128f71629ce4 +size 840 diff --git a/projects/draw_indirect/resources/cube/cube.blend b/projects/draw_indirect/resources/cube/cube.blend new file mode 100644 index 0000000000000000000000000000000000000000..62ccb2c742094bcfb5ed194ab905bffae86bfd65 --- /dev/null +++ b/projects/draw_indirect/resources/cube/cube.blend @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6c1e245f259c610528c9485db6688928faac0ab2addee9e3c2dde7740e4dd09 +size 774920 diff --git a/projects/draw_indirect/resources/cube/cube.blend1 b/projects/draw_indirect/resources/cube/cube.blend1 new file mode 100644 index 0000000000000000000000000000000000000000..13f21dcca218d7bc7a07a8a9682b5e1d9e607736 --- /dev/null +++ b/projects/draw_indirect/resources/cube/cube.blend1 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4496f423569b8ca81f3b3a55fad00f925557e0193fb9dbe6cdce7e71fb48f7b +size 774920 diff --git a/projects/draw_indirect/resources/cube/cube.glb b/projects/draw_indirect/resources/cube/cube.glb new file mode 100644 index 0000000000000000000000000000000000000000..66a42c65e71dcf375e04cc378256024dd3c7834d --- /dev/null +++ b/projects/draw_indirect/resources/cube/cube.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:198568b715f397d78f7c358c0f709a419e7fd677e54cdec7c19f71b5ed264897 +size 1194508 diff --git a/projects/draw_indirect/resources/cube/cube.gltf b/projects/draw_indirect/resources/cube/cube.gltf new file mode 100644 index 0000000000000000000000000000000000000000..428176144843dd06c78fe1d11a6392a0ea02b22d --- /dev/null +++ b/projects/draw_indirect/resources/cube/cube.gltf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f82f455647a84ca6242882ae26a79a499d3ce594f8de317ab89488c5b79721ac +size 2823 diff --git a/projects/draw_indirect/resources/shaders/shader.frag b/projects/draw_indirect/resources/shaders/shader.frag new file mode 100644 index 0000000000000000000000000000000000000000..71a1de69c57c0d7b7d4665095410e7acaf8dbd62 --- /dev/null +++ b/projects/draw_indirect/resources/shaders/shader.frag @@ -0,0 +1,14 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +layout(location = 0) in vec3 passNormal; +layout(location = 1) in vec2 passUV; + +layout(location = 0) out vec3 outColor; + +layout(set=0, binding=0) uniform texture2D meshTexture; +layout(set=0, binding=1) uniform sampler textureSampler; + +void main() { + outColor = texture(sampler2D(meshTexture, textureSampler), passUV).rgb; +} \ No newline at end of file diff --git a/projects/draw_indirect/resources/shaders/shader.vert b/projects/draw_indirect/resources/shaders/shader.vert new file mode 100644 index 0000000000000000000000000000000000000000..76855152253b48b7400f016d063ed4f0e507435e --- /dev/null +++ b/projects/draw_indirect/resources/shaders/shader.vert @@ -0,0 +1,19 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +layout(location = 0) in vec3 inPosition; +layout(location = 1) in vec3 inNormal; +layout(location = 2) in vec2 inUV; + +layout(location = 0) out vec3 passNormal; +layout(location = 1) out vec2 passUV; + +layout( push_constant ) uniform constants{ + mat4 mvp; +}; + +void main() { + gl_Position = mvp * vec4(inPosition, 1.0); + passNormal = inNormal; + passUV = inUV; +} \ No newline at end of file diff --git a/projects/draw_indirect/resources/triangle/Triangle.bin b/projects/draw_indirect/resources/triangle/Triangle.bin new file mode 100644 index 0000000000000000000000000000000000000000..57f26ad96592b64377e6aa93823d96a94e6c5022 --- /dev/null +++ b/projects/draw_indirect/resources/triangle/Triangle.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:412ebd5f7242c266b4957e7e26be13aa331dbcb7bbb854ab334a2437ae8ed959 +size 104 diff --git a/projects/draw_indirect/resources/triangle/Triangle.blend b/projects/draw_indirect/resources/triangle/Triangle.blend new file mode 100644 index 0000000000000000000000000000000000000000..2421dc5e1bb029d73a9ec09cc4530c5196851fd7 --- /dev/null +++ b/projects/draw_indirect/resources/triangle/Triangle.blend @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:387e544df173219fbf292a64a6656d1d782bbf71a5a9e9fdef0a308f47b05477 +size 758144 diff --git a/projects/draw_indirect/resources/triangle/Triangle.glb b/projects/draw_indirect/resources/triangle/Triangle.glb new file mode 100644 index 0000000000000000000000000000000000000000..4148620cd6af0dadbc791aa1c52bb5431a40884b --- /dev/null +++ b/projects/draw_indirect/resources/triangle/Triangle.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4be087a605212d139416b5352a018283b26b99260cbcddb7013a1beeb331227 +size 980 diff --git a/projects/draw_indirect/resources/triangle/Triangle.gltf b/projects/draw_indirect/resources/triangle/Triangle.gltf new file mode 100644 index 0000000000000000000000000000000000000000..a188e6ee16a5e8486cf307c7bda8cfd99bdbeea6 --- /dev/null +++ b/projects/draw_indirect/resources/triangle/Triangle.gltf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5fc354e040f79cff329e919677b194c75e3a522c6406f75c1108ad9575f12ec +size 2202 diff --git a/projects/draw_indirect/src/main.cpp b/projects/draw_indirect/src/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..731d3e56975ff0cd2d8e6d503a19d56de1b922fe --- /dev/null +++ b/projects/draw_indirect/src/main.cpp @@ -0,0 +1,219 @@ +#include <iostream> +#include <vkcv/Core.hpp> +#include <GLFW/glfw3.h> +#include <vkcv/camera/CameraManager.hpp> +#include <chrono> +#include <vkcv/asset/asset_loader.hpp> +#include <vkcv/shader/GLSLCompiler.hpp> + +int main(int argc, const char** argv) { + const char* applicationName = "First Mesh"; + + uint32_t windowWidth = 800; + uint32_t windowHeight = 600; + + vkcv::Window window = vkcv::Window::create( + applicationName, + windowWidth, + windowHeight, + true + ); + + vkcv::Core core = vkcv::Core::create( + window, + applicationName, + VK_MAKE_VERSION(0, 0, 1), + { vk::QueueFlagBits::eGraphics ,vk::QueueFlagBits::eCompute , vk::QueueFlagBits::eTransfer }, + {}, + { "VK_KHR_swapchain" } + ); + + vkcv::asset::Scene mesh; + + const char* path = argc > 1 ? argv[1] : "resources/cube/cube.gltf"; + int result = vkcv::asset::loadScene(path, mesh); + + if (result == 1) { + std::cout << "Mesh loading successful!" << std::endl; + } else { + std::cerr << "Mesh loading failed: " << result << std::endl; + return 1; + } + + assert(!mesh.vertexGroups.empty()); + auto vertexBuffer = core.createBuffer<uint8_t>( + vkcv::BufferType::VERTEX, + mesh.vertexGroups[0].vertexBuffer.data.size(), + vkcv::BufferMemoryType::DEVICE_LOCAL + ); + + vertexBuffer.fill(mesh.vertexGroups[0].vertexBuffer.data); + + auto indexBuffer = core.createBuffer<uint8_t>( + vkcv::BufferType::INDEX, + mesh.vertexGroups[0].indexBuffer.data.size(), + vkcv::BufferMemoryType::DEVICE_LOCAL + ); + + indexBuffer.fill(mesh.vertexGroups[0].indexBuffer.data); + + // an example attachment for passes that output to the window + const vkcv::AttachmentDescription present_color_attachment( + vkcv::AttachmentOperation::STORE, + vkcv::AttachmentOperation::CLEAR, + core.getSwapchain().getFormat() + ); + + const vkcv::AttachmentDescription depth_attachment( + vkcv::AttachmentOperation::STORE, + vkcv::AttachmentOperation::CLEAR, + vk::Format::eD32Sfloat + ); + + vkcv::PassConfig firstMeshPassDefinition({ present_color_attachment, depth_attachment }); + vkcv::PassHandle firstMeshPass = core.createPass(firstMeshPassDefinition); + + if (!firstMeshPass) { + std::cerr << "Error. Could not create renderpass. Exiting." << std::endl; + return EXIT_FAILURE; + } + + vkcv::ShaderProgram firstMeshProgram; + vkcv::shader::GLSLCompiler compiler; + + compiler.compile(vkcv::ShaderStage::VERTEX, std::filesystem::path("resources/shaders/shader.vert"), + [&firstMeshProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { + firstMeshProgram.addShader(shaderStage, path); + }); + + compiler.compile(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("resources/shaders/shader.frag"), + [&firstMeshProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { + firstMeshProgram.addShader(shaderStage, path); + }); + + auto& attributes = mesh.vertexGroups[0].vertexBuffer.attributes; + + + std::sort(attributes.begin(), attributes.end(), [](const vkcv::asset::VertexAttribute& x, const vkcv::asset::VertexAttribute& y) { + return static_cast<uint32_t>(x.type) < static_cast<uint32_t>(y.type); + }); + + const std::vector<vkcv::VertexAttachment> vertexAttachments = firstMeshProgram.getVertexAttachments(); + std::vector<vkcv::VertexBinding> bindings; + for (size_t i = 0; i < vertexAttachments.size(); i++) { + bindings.push_back(vkcv::VertexBinding(i, { vertexAttachments[i] })); + } + + const vkcv::VertexLayout firstMeshLayout (bindings); + + uint32_t setID = 0; + std::vector<vkcv::DescriptorBinding> descriptorBindings = { firstMeshProgram.getReflectedDescriptors()[setID] }; + vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorBindings); + + const vkcv::PipelineConfig firstMeshPipelineConfig { + firstMeshProgram, + UINT32_MAX, + UINT32_MAX, + firstMeshPass, + {firstMeshLayout}, + { core.getDescriptorSet(descriptorSet).layout }, + true + }; + vkcv::PipelineHandle firstMeshPipeline = core.createGraphicsPipeline(firstMeshPipelineConfig); + + if (!firstMeshPipeline) { + std::cerr << "Error. Could not create graphics pipeline. Exiting." << std::endl; + return EXIT_FAILURE; + } + + if (mesh.textures.empty()) { + std::cerr << "Error. No textures found. Exiting." << std::endl; + return EXIT_FAILURE; + } + + vkcv::asset::Texture &tex = mesh.textures[0]; + vkcv::Image texture = core.createImage(vk::Format::eR8G8B8A8Srgb, tex.w, tex.h); + texture.fill(tex.data.data()); + texture.generateMipChainImmediate(); + texture.switchLayout(vk::ImageLayout::eShaderReadOnlyOptimal); + + vkcv::SamplerHandle sampler = core.createSampler( + vkcv::SamplerFilterType::LINEAR, + vkcv::SamplerFilterType::LINEAR, + vkcv::SamplerMipmapMode::LINEAR, + vkcv::SamplerAddressMode::REPEAT + ); + + const std::vector<vkcv::VertexBufferBinding> vertexBufferBindings = { + vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[0].offset), vertexBuffer.getVulkanHandle()), + vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[1].offset), vertexBuffer.getVulkanHandle()), + vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[2].offset), vertexBuffer.getVulkanHandle()) }; + + vkcv::DescriptorWrites setWrites; + setWrites.sampledImageWrites = { vkcv::SampledImageDescriptorWrite(0, texture.getHandle()) }; + setWrites.samplerWrites = { vkcv::SamplerDescriptorWrite(1, sampler) }; + + core.writeDescriptorSet(descriptorSet, setWrites); + + vkcv::ImageHandle depthBuffer = core.createImage(vk::Format::eD32Sfloat, windowWidth, windowHeight, 1, false).getHandle(); + + const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); + + const vkcv::Mesh renderMesh(vertexBufferBindings, indexBuffer.getVulkanHandle(), mesh.vertexGroups[0].numIndices); + + vkcv::DescriptorSetUsage descriptorUsage(0, core.getDescriptorSet(descriptorSet).vulkanHandle); + vkcv::DrawcallInfo drawcall(renderMesh, { descriptorUsage },1); + + vkcv::camera::CameraManager cameraManager(window); + uint32_t camIndex0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); + uint32_t camIndex1 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL); + + cameraManager.getCamera(camIndex0).setPosition(glm::vec3(0, 0, -3)); + + auto start = std::chrono::system_clock::now(); + + while (window.isWindowOpen()) { + vkcv::Window::pollEvents(); + + if(window.getHeight() == 0 || window.getWidth() == 0) + continue; + + uint32_t swapchainWidth, swapchainHeight; + if (!core.beginFrame(swapchainWidth, swapchainHeight)) { + continue; + } + + if ((swapchainWidth != windowWidth) || ((swapchainHeight != windowHeight))) { + depthBuffer = core.createImage(vk::Format::eD32Sfloat, swapchainWidth, swapchainHeight).getHandle(); + + windowWidth = swapchainWidth; + windowHeight = swapchainHeight; + } + + 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::PushConstants pushConstants (sizeof(glm::mat4)); + pushConstants.appendDrawcall(mvp); + + const std::vector<vkcv::ImageHandle> renderTargets = { swapchainInput, depthBuffer }; + auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); + + core.recordDrawcallsToCmdStream( + cmdStream, + firstMeshPass, + firstMeshPipeline, + pushConstants, + { drawcall }, + renderTargets); + core.prepareSwapchainImageForPresent(cmdStream); + core.submitCommandStream(cmdStream); + core.endFrame(); + } + + return 0; +}