From caf7997f36e4720736436fc720611b3358aa1e83 Mon Sep 17 00:00:00 2001
From: Sebastian Gaida <gaida@ca-digit.com>
Date: Tue, 6 Jul 2021 12:58:13 +0200
Subject: [PATCH] [#87] add bunny into scene

---
 include/vkcv/DrawcallRecording.hpp            |  11 +-
 projects/mesh_shader/CMakeLists.txt           |   2 +-
 .../mesh_shader/resources/Bunny/Bunny.gltf    |   3 +
 .../mesh_shader/resources/shaders/shader.frag |   4 +-
 .../mesh_shader/resources/shaders/shader.vert |  21 ++--
 projects/mesh_shader/src/main.cpp             | 111 +++++++++++++-----
 projects/mesh_shader/src/mesh.hpp             |   5 +
 src/vkcv/DrawcallRecording.cpp                |  13 +-
 8 files changed, 124 insertions(+), 46 deletions(-)
 create mode 100644 projects/mesh_shader/resources/Bunny/Bunny.gltf
 create mode 100644 projects/mesh_shader/src/mesh.hpp

diff --git a/include/vkcv/DrawcallRecording.hpp b/include/vkcv/DrawcallRecording.hpp
index 50fb0846..c0ad2250 100644
--- a/include/vkcv/DrawcallRecording.hpp
+++ b/include/vkcv/DrawcallRecording.hpp
@@ -12,6 +12,11 @@ namespace vkcv {
         vk::Buffer      buffer;
     };
 
+    enum class IndexBitCount{
+        Bit16,
+        Bit32
+    };
+
     struct DescriptorSetUsage {
         inline DescriptorSetUsage(uint32_t setLocation, vk::DescriptorSet vulkanHandle) noexcept
             : setLocation(setLocation), vulkanHandle(vulkanHandle) {}
@@ -21,12 +26,14 @@ namespace vkcv {
     };
 
     struct Mesh {
-        inline Mesh(std::vector<VertexBufferBinding> vertexBufferBindings, vk::Buffer indexBuffer, size_t indexCount) noexcept
-            : vertexBufferBindings(vertexBufferBindings), indexBuffer(indexBuffer), indexCount(indexCount){}
+        inline Mesh(std::vector<VertexBufferBinding> vertexBufferBindings, vk::Buffer indexBuffer, size_t indexCount, IndexBitCount indexBitCount = IndexBitCount::Bit16) noexcept
+            : vertexBufferBindings(vertexBufferBindings), indexBuffer(indexBuffer), indexCount(indexCount), indexBitCount(indexBitCount){}
 
         std::vector<VertexBufferBinding>    vertexBufferBindings;
         vk::Buffer                          indexBuffer;
         size_t                              indexCount;
+        IndexBitCount                       indexBitCount;
+
     };
 
     struct PushConstantData {
diff --git a/projects/mesh_shader/CMakeLists.txt b/projects/mesh_shader/CMakeLists.txt
index 0b2847cd..ba9ce472 100644
--- a/projects/mesh_shader/CMakeLists.txt
+++ b/projects/mesh_shader/CMakeLists.txt
@@ -25,4 +25,4 @@ endif()
 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)
+target_link_libraries(mesh_shader vkcv ${vkcv_libraries} vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv_testing vkcv_camera vkcv_shader_compiler vkcv_gui)
\ No newline at end of file
diff --git a/projects/mesh_shader/resources/Bunny/Bunny.gltf b/projects/mesh_shader/resources/Bunny/Bunny.gltf
new file mode 100644
index 00000000..3b5eefbc
--- /dev/null
+++ b/projects/mesh_shader/resources/Bunny/Bunny.gltf
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:97970b941a690d4538c8d8989dd5a8bfae180bb117ba7e22c59e0a4d119e5a2f
+size 5395743
diff --git a/projects/mesh_shader/resources/shaders/shader.frag b/projects/mesh_shader/resources/shaders/shader.frag
index 37a98da8..11d4f36e 100644
--- a/projects/mesh_shader/resources/shaders/shader.frag
+++ b/projects/mesh_shader/resources/shaders/shader.frag
@@ -2,8 +2,10 @@
 #extension GL_ARB_separate_shader_objects : enable
 
 layout(location = 0) in vec3 VertexColor;
+layout(location = 1) in vec3 passNormal;
 layout(location = 0) out vec4 outColor;
 
 void main() {
-	outColor = vec4(VertexColor, 1);
+	vec3 vis = normalize(passNormal) * 0.5 +0.5;
+	outColor = vec4(vis , 1);
 }
\ No newline at end of file
diff --git a/projects/mesh_shader/resources/shaders/shader.vert b/projects/mesh_shader/resources/shaders/shader.vert
index e129186a..425fc412 100644
--- a/projects/mesh_shader/resources/shaders/shader.vert
+++ b/projects/mesh_shader/resources/shaders/shader.vert
@@ -1,25 +1,18 @@
 #version 450
 #extension GL_ARB_separate_shader_objects : enable
 
+layout(location = 0) in vec3 inPosition;
+layout(location = 1) in vec3 inNormal;
+
 layout(location = 0) out vec3 fragColor;
+layout(location = 1) out vec3 passNormal;
 
 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];
+    gl_Position = mvp * vec4(inPosition, 1.0);
+    passNormal  = inNormal;
+	fragColor = vec3(1.f);
 }
\ No newline at end of file
diff --git a/projects/mesh_shader/src/main.cpp b/projects/mesh_shader/src/main.cpp
index 8a423345..f1dffa05 100644
--- a/projects/mesh_shader/src/main.cpp
+++ b/projects/mesh_shader/src/main.cpp
@@ -6,6 +6,7 @@
 
 #include <vkcv/shader/GLSLCompiler.hpp>
 #include <vkcv/gui/GUI.hpp>
+#include <vkcv/asset/asset_loader.hpp>
 
 int main(int argc, const char** argv) {
 	const char* applicationName = "Mesh shader";
@@ -27,20 +28,52 @@ int main(int argc, const char** argv) {
 		{},
 		{ "VK_KHR_swapchain", VK_NV_MESH_SHADER_EXTENSION_NAME }
 	);
-	
-	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();
+    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();
+
+    vkcv::asset::Scene mesh;
+    const char* path = argc > 1 ? argv[1] : "resources/Bunny/Bunny.gltf";
+    vkcv::asset::loadScene(path, mesh);
+
+    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);
+
+    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 vkcv::AttachmentDescription present_color_attachment(
 		vkcv::AttachmentOperation::STORE,
 		vkcv::AttachmentOperation::CLEAR,
 		core.getSwapchain().getFormat());
 
-	vkcv::PassConfig trianglePassDefinition({ present_color_attachment });
+    const vkcv::AttachmentDescription depth_attachment(
+            vkcv::AttachmentOperation::STORE,
+            vkcv::AttachmentOperation::CLEAR,
+            vk::Format::eD32Sfloat
+    );
+
+	vkcv::PassConfig trianglePassDefinition({ present_color_attachment, depth_attachment });
 	vkcv::PassHandle renderPass = core.createPass(trianglePassDefinition);
 
 	if (!renderPass)
@@ -49,30 +82,41 @@ int main(int argc, const char** argv) {
 		return EXIT_FAILURE;
 	}
 
-	vkcv::ShaderProgram triangleShaderProgram{};
+	vkcv::ShaderProgram bunnyShaderProgram{};
 	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);
+					 [&bunnyShaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
+		 bunnyShaderProgram.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);
+					 [&bunnyShaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
+		bunnyShaderProgram.addShader(shaderStage, path);
 	});
 
-	const vkcv::PipelineConfig trianglePipelineDefinition {
-		triangleShaderProgram,
-		(uint32_t)windowWidth,
-		(uint32_t)windowHeight,
-		renderPass,
-		{},
-		{},
-		false
+    const std::vector<vkcv::VertexAttachment> vertexAttachments = bunnyShaderProgram.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 meshShaderLayout (bindings);
+
+    uint32_t setID = 0;
+//    std::vector<vkcv::DescriptorBinding> descriptorBindings = {bunnyShaderProgram.getReflectedDescriptors()[setID] };
+//    vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorBindings);
+
+	const vkcv::PipelineConfig bunnyPipelineDefinition {
+            bunnyShaderProgram,
+            (uint32_t)windowWidth,
+            (uint32_t)windowHeight,
+            renderPass,
+            { meshShaderLayout },
+            {},
+            false
 	};
 
-	vkcv::PipelineHandle trianglePipeline = core.createGraphicsPipeline(trianglePipelineDefinition);
+	vkcv::PipelineHandle trianglePipeline = core.createGraphicsPipeline(bunnyPipelineDefinition);
 
 	if (!trianglePipeline)
 	{
@@ -115,12 +159,23 @@ int main(int argc, const char** argv) {
 		return EXIT_FAILURE;
 	}
 
-	auto start = std::chrono::system_clock::now();
+    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;
+
+    vkcv::ImageHandle depthBuffer = core.createImage(vk::Format::eD32Sfloat, windowWidth, windowHeight, 1, false).getHandle();
+
+    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::Mesh renderMesh(vertexBufferBindings, indexBuffer.getVulkanHandle(), mesh.vertexGroups[0].numIndices, vkcv::IndexBitCount::Bit32);
+
+//    vkcv::DescriptorSetUsage    descriptorUsage(0, core.getDescriptorSet(descriptorSet).vulkanHandle);
+    vkcv::DrawcallInfo          drawcall(renderMesh, {});
 
 	const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle();
 
@@ -146,8 +201,11 @@ int main(int argc, const char** argv) {
         glm::mat4 mvp = cameraManager.getActiveCamera().getMVP();
 
 		vkcv::PushConstantData pushConstantData((void*)&mvp, sizeof(glm::mat4));
+
+        const std::vector<vkcv::ImageHandle> renderTargets = { swapchainInput, depthBuffer };
 		auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics);
 
+		/*
 		core.recordMeshShaderDrawcalls(
 			cmdStream,
 			renderPass,
@@ -155,16 +213,15 @@ int main(int argc, const char** argv) {
 			pushConstantData,
 			{ vkcv::MeshShaderDrawcall({}, 1) },
 			{ swapchainInput });
+		*/
 
-		/*
 		core.recordDrawcallsToCmdStream(
 			cmdStream,
 			renderPass,
 			trianglePipeline,
 			pushConstantData,
 			{ drawcall },
-			{ swapchainInput });
-		*/
+			{ renderTargets });
 
 		core.prepareSwapchainImageForPresent(cmdStream);
 		core.submitCommandStream(cmdStream);
diff --git a/projects/mesh_shader/src/mesh.hpp b/projects/mesh_shader/src/mesh.hpp
new file mode 100644
index 00000000..9a21bb4f
--- /dev/null
+++ b/projects/mesh_shader/src/mesh.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+struct Mesh{
+
+};
\ No newline at end of file
diff --git a/src/vkcv/DrawcallRecording.cpp b/src/vkcv/DrawcallRecording.cpp
index bfea043d..86eaa0a5 100644
--- a/src/vkcv/DrawcallRecording.cpp
+++ b/src/vkcv/DrawcallRecording.cpp
@@ -1,7 +1,18 @@
 #include <vkcv/DrawcallRecording.hpp>
+#include <vkcv/Logger.hpp>
 
 namespace vkcv {
 
+    vk::IndexType getIndexType(IndexBitCount indexByteCount){
+        switch (indexByteCount) {
+            case IndexBitCount::Bit16: return vk::IndexType::eUint16;
+            case IndexBitCount::Bit32: return vk::IndexType::eUint32;
+            default:
+                vkcv_log(LogLevel::ERROR, "unknown Enum");
+                return vk::IndexType::eUint16;
+        }
+    }
+
     void recordDrawcall(
         const DrawcallInfo      &drawcall,
         vk::CommandBuffer       cmdBuffer,
@@ -35,7 +46,7 @@ namespace vkcv {
             drawcallPushConstantData);
 
         if (drawcall.mesh.indexBuffer) {
-            cmdBuffer.bindIndexBuffer(drawcall.mesh.indexBuffer, 0, vk::IndexType::eUint16);	//FIXME: choose proper size
+            cmdBuffer.bindIndexBuffer(drawcall.mesh.indexBuffer, 0, getIndexType(drawcall.mesh.indexBitCount));
             cmdBuffer.drawIndexed(drawcall.mesh.indexCount, 1, 0, 0, {});
         }
         else {
-- 
GitLab