From e59529d3f55b9128f798a7f02a7288f96bdaf9a4 Mon Sep 17 00:00:00 2001 From: Chuyan Zhang Date: Thu, 3 Oct 2024 19:49:47 -0700 Subject: use xmake build & scene load wip --- .gitignore | 1 + .gitmodules | 3 ++ CMakeLists.txt | 5 ++- ext/glm | 1 + src/gltf_loader.cpp | 96 ++++++++++++++++++++++++++++++++++++++++++++++++ src/gltf_loader.h | 11 ++++++ src/render_assets.h | 38 +++++++++++++++++++ src/vulkan_helper.cpp | 3 +- src/vulkan_helper.h | 6 ++- src/vulkan_swapchain.cpp | 2 +- src/vulkan_swapchain.h | 1 + xmake.lua | 78 +++++++++++++++++++++++++++++++++++++++ 12 files changed, 239 insertions(+), 6 deletions(-) create mode 160000 ext/glm create mode 100644 src/gltf_loader.cpp create mode 100644 src/gltf_loader.h create mode 100644 src/render_assets.h create mode 100644 xmake.lua diff --git a/.gitignore b/.gitignore index 352a5fd..41e7059 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,7 @@ build/ # clangd config .clangd +.xmake # imgui config file imgui.ini diff --git a/.gitmodules b/.gitmodules index 0d0d572..ffb9b3a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,3 +16,6 @@ [submodule "ext/stb"] path = ext/stb url = https://github.com/nothings/stb +[submodule "ext/glm"] + path = ext/glm + url = https://github.com/g-truc/glm.git diff --git a/CMakeLists.txt b/CMakeLists.txt index afe7626..ad7fd44 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ add_library(argparse INTERFACE) target_include_directories(argparse INTERFACE ${EXT_DIR}/argparse/include) add_library(tinygltf INTERFACE) -target_include_directories(tinygltf INTERFACE ${EXT_DIR}/tinygltf) +target_include_directories(tinygltf INTERFACE ${EXT_DIR}/tinygltf.git) add_library(tinyobjloader INTERFACE) target_include_directories(tinyobjloader INTERFACE ${EXT_DIR}/tinyobjloader) @@ -33,6 +33,9 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug") add_compile_definitions(USE_VULKAN_VALIDATION_LAYERS) endif() +add_subdirectory(${EXT_DIR}/glm) +target_link_libraries(iris_renderer PRIVATE glm::glm) + find_package(glfw3 REQUIRED) target_link_libraries(iris_renderer PRIVATE glfw) diff --git a/ext/glm b/ext/glm new file mode 160000 index 0000000..33b4a62 --- /dev/null +++ b/ext/glm @@ -0,0 +1 @@ +Subproject commit 33b4a621a697a305bc3a7610d290677b96beb181 diff --git a/src/gltf_loader.cpp b/src/gltf_loader.cpp new file mode 100644 index 0000000..2b3818f --- /dev/null +++ b/src/gltf_loader.cpp @@ -0,0 +1,96 @@ +#include "gltf_loader.h" +#include "spdlog/spdlog.h" + +enum class SceneFileType { + GLTF, + GLB, + UNKNOWN, +}; + +bool load_gltf(const std::string_view path, iris::Scene &scene) { + tinygltf::Model model; + tinygltf::TinyGLTF loader; + + std::string error; + std::string warning; + + SceneFileType file_type = [&path] { + if (path.find_last_of(".") != std::string::npos) { + std::string_view extension = path.substr(path.find_last_of(".") + 1); + if (extension == "glb") { + return SceneFileType::GLB; + } else if (extension == "gltf") { + return SceneFileType::GLTF; + } + } + return SceneFileType::UNKNOWN; + }(); + switch (file_type) { + case SceneFileType::GLTF: + if (!loader.LoadASCIIFromFile(&model, &error, &warning, path.data())) { + spdlog::error("Failed to load glTF file: {}", error); + return false; + } + break; + case SceneFileType::GLB: + if (!loader.LoadBinaryFromFile(&model, &error, &warning, path.data())) { + spdlog::error("Failed to load glTF file: {}", error); + return false; + } + break; + case SceneFileType::UNKNOWN: + spdlog::error("Unknown file type: {}", path); + return false; + } + + spdlog::info("loaded glTF file {} has:\n" + "{} accessors\n" + "{} animations\n" + "{} buffers\n" + "{} bufferViews\n" + "{} materials\n" + "{} meshes\n" + "{} nodes\n" + "{} textures\n" + "{} images\n" + "{} skins\n" + "{} samplers\n" + "{} cameras\n" + "{} scenes\n" + "{} lights", + path, + model.accessors.size(), + model.animations.size(), + model.buffers.size(), + model.bufferViews.size(), + model.materials.size(), + model.meshes.size(), + model.nodes.size(), + model.textures.size(), + model.images.size(), + model.skins.size(), + model.samplers.size(), + model.cameras.size(), + model.scenes.size(), + model.lights.size()); + + for (const auto &mesh : model.meshes) { + iris::Mesh iris_mesh; + for (const auto &primitive : mesh.primitives) { + const auto &position_accessor = model.accessors[primitive.attributes.at("POSITION")]; + const auto &position_buffer_view = model.bufferViews[position_accessor.bufferView]; + const auto &position_buffer = model.buffers[position_buffer_view.buffer]; + const auto &position_data = reinterpret_cast(position_buffer.data.data() + position_buffer_view.byteOffset + position_accessor.byteOffset); + + const auto &index_accessor = model.accessors[primitive.indices]; + const auto &index_buffer_view = model.bufferViews[index_accessor.bufferView]; + const auto &index_buffer = model.buffers[index_buffer_view.buffer]; + const auto &index_data = reinterpret_cast(index_buffer.data.data() + index_buffer_view.byteOffset + index_accessor.byteOffset); + + iris_mesh.vertices.insert(iris_mesh.vertices.end(), position_data, position_data + position_accessor.count * 3); + iris_mesh.indices.insert(iris_mesh.indices.end(), index_data, index_data + index_accessor.count); + } + scene.meshes.push_back(iris_mesh); + } + return true; +} \ No newline at end of file diff --git a/src/gltf_loader.h b/src/gltf_loader.h new file mode 100644 index 0000000..c239bb2 --- /dev/null +++ b/src/gltf_loader.h @@ -0,0 +1,11 @@ +#pragma once + +#include +#include "render_assets.h" + +#define TINYGLTF_IMPLEMENTATION +#define STB_IMAGE_IMPLEMENTATION +#define STB_IMAGE_WRITE_IMPLEMENTATION +#include "tiny_gltf.h" + +bool load_gltf(const std::string_view path, iris::Scene &scene); \ No newline at end of file diff --git a/src/render_assets.h b/src/render_assets.h new file mode 100644 index 0000000..763bf76 --- /dev/null +++ b/src/render_assets.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include +#include + +namespace iris { + +template +struct Mesh { + std::string name; + std::vector vertices; + std::vector indices; +}; + +struct Material { + +}; + +struct Texture { +}; + +struct Camera { + glm::vec3 position; + glm::vec3 direction; + glm::vec3 up; +}; + +struct Scene { + std::vector> meshes; + std::vector materials; + std::vector textures; + + Camera camera_position; +}; + +} // namespace iris \ No newline at end of file diff --git a/src/vulkan_helper.cpp b/src/vulkan_helper.cpp index 567d414..c281b2c 100644 --- a/src/vulkan_helper.cpp +++ b/src/vulkan_helper.cpp @@ -2,7 +2,6 @@ #include "vulkan/vulkan_core.h" #include #include -#define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" #include #include @@ -281,7 +280,7 @@ CommandBuffer::CommandBuffer(VkDevice device, spdlog::debug("Created fence: 0x{:x}", (uint64_t)fence); } -void CommandBuffer::destroy() { +void CommandBuffer::release() { if (fence != VK_NULL_HANDLE) { vkDestroyFence(device, fence, VK_NULL_HANDLE); vkFreeCommandBuffers(device, pool, 1, &buffer); diff --git a/src/vulkan_helper.h b/src/vulkan_helper.h index 6dbf0b7..04fcead 100644 --- a/src/vulkan_helper.h +++ b/src/vulkan_helper.h @@ -1,3 +1,5 @@ +#pragma once + #include #include #include @@ -63,10 +65,10 @@ struct CommandBuffer { VkQueue queue; CommandBuffer(VkDevice device, uint32_t queue_family_index, VkQueue queue); - void destroy(); + void release(); void begin(VkCommandBufferUsageFlags flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); void submit_sync(); - ~CommandBuffer() { destroy(); } + ~CommandBuffer() { release(); } }; struct Device { diff --git a/src/vulkan_swapchain.cpp b/src/vulkan_swapchain.cpp index c38e9f6..4e08049 100644 --- a/src/vulkan_swapchain.cpp +++ b/src/vulkan_swapchain.cpp @@ -525,7 +525,7 @@ void Swapchain::display(Texture2D& texture) { void Swapchain::release() { upload_texture->release(); - cmd_buf.destroy(); + cmd_buf.release(); for (uint32_t i = 0; i < SWAPCHAIN_IMAGE_COUNT; i++) { vkDestroyFramebuffer(device.device, framebuffers[i], nullptr); diff --git a/src/vulkan_swapchain.h b/src/vulkan_swapchain.h index 381c5b0..8d4604e 100644 --- a/src/vulkan_swapchain.h +++ b/src/vulkan_swapchain.h @@ -1,3 +1,4 @@ +#pragma once #include "imgui_impl_glfw.h" #include "vulkan_helper.h" #include "vulkan/vulkan_core.h" diff --git a/xmake.lua b/xmake.lua new file mode 100644 index 0000000..1b9730f --- /dev/null +++ b/xmake.lua @@ -0,0 +1,78 @@ +add_rules("mode.debug", "mode.release") + +-- Project settings +set_project("iris_renderer") +set_version("1.0") +set_languages("c++20") + + +-- Project directories +local project_root = os.projectdir() +local src_dir = path.join(project_root, "src") +local ext_dir = path.join(project_root, "ext") + +-- ImGui target +target("imgui") + set_kind("static") + local imgui_dir = path.join(ext_dir, "imgui") + + -- Add source files + add_files( + path.join(imgui_dir, "imgui.cpp"), + path.join(imgui_dir, "imgui_demo.cpp"), + path.join(imgui_dir, "imgui_draw.cpp"), + path.join(imgui_dir, "imgui_tables.cpp"), + path.join(imgui_dir, "imgui_widgets.cpp"), + path.join(imgui_dir, "backends/imgui_impl_glfw.cpp"), + path.join(imgui_dir, "backends/imgui_impl_vulkan.cpp") + ) + + -- Add include directories + add_includedirs( + imgui_dir, + path.join(imgui_dir, "backends"), + {public = true} + ) + +-- Arguments for compilation +target("argparse") + set_kind("headeronly") + add_includedirs(path.join(ext_dir, "argparse/include"), {public = true}) + +target("tinygltf") + set_kind("headeronly") + add_includedirs(path.join(ext_dir, "tinygltf.git"), {public = true}) + add_cxxflags("-w") + +target("tinyobjloader") + set_kind("headeronly") + add_includedirs(path.join(ext_dir, "tinyobjloader"), {public = true}) + +target("stb") + set_kind("headeronly") + add_includedirs(path.join(ext_dir, "stb"), {public = true}) + +-- Main executable target +target("iris_renderer") + set_kind("binary") + add_files(path.join(src_dir, "**.cpp")) + + -- Link external libraries + add_deps("argparse", "imgui", "tinygltf", "tinyobjloader", "stb") + + -- Add libraries + add_packages("vulkansdk", "glfw", "fmt", "vulkan-memory-allocator", "spdlog", "glm") + add_syslinks("vulkan", "glfw", "fmt") + + -- OS-specific libraries (dl, pthread, X11, etc.) + if is_plat("linux") then + add_syslinks("dl", "pthread", "X11", "Xxf86vm", "Xrandr", "Xi") + end + + -- Compiler options + add_cxxflags("-Wall", "-Wextra", "-Wno-missing-field-initializers") + + -- Vulkan validation layers for debug builds + if is_mode("debug") then + add_defines("USE_VULKAN_VALIDATION_LAYERS") + end -- cgit v1.2.3-70-g09d2