diff --git a/BasaltPresenter/CMakeLists.txt b/BasaltPresenter/CMakeLists.txt index 3926fbf..b73068f 100644 --- a/BasaltPresenter/CMakeLists.txt +++ b/BasaltPresenter/CMakeLists.txt @@ -41,12 +41,16 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake" ) # Find required packages based on options +find_package(spdlog REQUIRED) if (BASALT_CUDA_DELIVER) find_package(CUDA REQUIRED) endif () if (BASALT_DIRECTX11_ENGINE) find_package(DirectX11 REQUIRED) endif () +if (BASALT_OBJ_OBJECT_LOADER) + find_package(tinyobjloader REQUIRED) +endif () # Include projects diff --git a/BasaltPresenter/Plugins/ObjectLoader/ObjObjectLoader/CMakeLists.txt b/BasaltPresenter/Plugins/ObjectLoader/ObjObjectLoader/CMakeLists.txt index 052ba6b..39d08f9 100644 --- a/BasaltPresenter/Plugins/ObjectLoader/ObjObjectLoader/CMakeLists.txt +++ b/BasaltPresenter/Plugins/ObjectLoader/ObjObjectLoader/CMakeLists.txt @@ -14,6 +14,7 @@ PRIVATE target_link_libraries(BasaltObjObjectLoader PRIVATE BasaltShared + tinyobjloader ) # Enable export macro target_compile_definitions(BasaltObjObjectLoader diff --git a/BasaltPresenter/Plugins/ObjectLoader/ObjObjectLoader/main.cpp b/BasaltPresenter/Plugins/ObjectLoader/ObjObjectLoader/main.cpp index ab428f5..4ff5cbc 100644 --- a/BasaltPresenter/Plugins/ObjectLoader/ObjObjectLoader/main.cpp +++ b/BasaltPresenter/Plugins/ObjectLoader/ObjObjectLoader/main.cpp @@ -1,9 +1,95 @@ #include +#include +#include +#include +#include + +namespace object_loader = ::basalt::shared::object_loader; +using object_loader::IObjectLoader; +using object_loader::Object; +using object_loader::ObjectLoaderConfig; +namespace math = ::basalt::shared::math; +using math::FloatPoint; +using math::Index; +using math::Triangle; +using math::Vector3; + +class ObjObjectLoader : public IObjectLoader { +public: + ObjObjectLoader() {} + virtual ~ObjObjectLoader() {} + +public: + virtual void load(ObjectLoaderConfig&& config) override { + IObjectLoader::load(std::move(config)); + + // Load the OBJ file using tinyobjloader + tinyobj::attrib_t attrib; + std::vector shapes; + std::vector materials; + std::string err; + + // Load the OBJ file + if (!tinyobj::LoadObj(&attrib, &shapes, &materials, &err, this->config.filename.c_str())) { + throw std::runtime_error("fail to load obj file"); + } + + // Create one object from all shapes in the OBJ file + std::vector vertices; + std::vector triangles; + + // Extract all vertices from the OBJ file + // In tinyobjloader, vertices are stored in a flat array [x,y,z,x,y,z,...] + size_t num_vertices = attrib.vertices.size() / 3; + vertices.reserve(num_vertices); + + for (size_t i = 0; i < attrib.vertices.size(); i += 3) { + Vector3 vertex; + vertex.x = attrib.vertices[i + 0]; // x coordinate + vertex.y = attrib.vertices[i + 1]; // y coordinate + vertex.z = attrib.vertices[i + 2]; // z coordinate + vertices.emplace_back(vertex); + } + + // Process each shape and add its triangles + for (const auto& shape : shapes) { + // Add triangles from this shape to our collection + // Each face in the shape has been triangulated by tinyobjloader + for (size_t i = 0; i < shape.mesh.indices.size(); i += 3) { + if (i + 2 < shape.mesh.indices.size()) { + Triangle triangle; + + // Get the three indices that form the triangle + // vertex_index is the index into the attrib.vertices array + int idx0 = shape.mesh.indices[i + 0].vertex_index; + int idx1 = shape.mesh.indices[i + 1].vertex_index; + int idx2 = shape.mesh.indices[i + 2].vertex_index; + + // Make sure indices are valid + if (idx0 >= 0 && idx1 >= 0 && idx2 >= 0) { + triangle.i = static_cast(idx0); + triangle.j = static_cast(idx1); + triangle.k = static_cast(idx2); + + triangles.emplace_back(triangle); + } + } + } + } + + // Create an Object and add it to our objects vector + if (vertices.empty() || triangles.empty()) { + throw std::runtime_error("empty scene is not allowed"); + } else { + this->objects.emplace_back(std::move(vertices), std::move(triangles)); + } + } +}; BS_EXPORT void* BSCreateInstance() { - return nullptr; + return static_cast(new ObjObjectLoader()); } BS_EXPORT void BSDestroyInstance(void* instance) { - return; + delete dynamic_cast(static_cast(instance)); } diff --git a/BasaltPresenter/Presenter/main.cpp b/BasaltPresenter/Presenter/main.cpp index bfad3eb..0681a67 100644 --- a/BasaltPresenter/Presenter/main.cpp +++ b/BasaltPresenter/Presenter/main.cpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace engine = ::basalt::shared::engine; using engine::EngineConfig; @@ -20,18 +21,22 @@ using ::basalt::presenter::cmd_client::CmdClient; using ::basalt::presenter::stopwatch::Stopwatch; int main(int argc, char* argv[]) { + spdlog::info("Finding plugins..."); auto engine_dll = DllLoader(DllKind::Engine, BSTEXT("BasaltDirectX11Engine")); auto deliver_dll = DllLoader(DllKind::Deliver, BSTEXT("BasaltPipeDeliver")); auto client = CmdClient(); + spdlog::info("Waiting BasaltTrainer..."); auto payload = client.wait_handshake(); + spdlog::info("Allocating resources..."); auto* engine = engine_dll.create_instance(); //auto* deliver = deliver_dll.create_instance(); EngineConfig engine_config{.headless = false, .width = payload.width, .height = payload.height}; engine->startup(std::move(engine_config)); + spdlog::info("Start to running."); Stopwatch stopwatch(120); while (true) { auto req_stop = engine->tick(); @@ -40,6 +45,9 @@ int main(int argc, char* argv[]) { if (can_stop) break; } + spdlog::info("Destroying resources..."); engine->shutdown(); engine_dll.destroy_instance(engine); + + spdlog::info("Program stop."); } diff --git a/BasaltPresenter/Presenter/stopwatch.cpp b/BasaltPresenter/Presenter/stopwatch.cpp index 95fc597..34da384 100644 --- a/BasaltPresenter/Presenter/stopwatch.cpp +++ b/BasaltPresenter/Presenter/stopwatch.cpp @@ -1,5 +1,5 @@ #include "stopwatch.hpp" -#include +#include namespace basalt::presenter::stopwatch { @@ -20,7 +20,7 @@ namespace basalt::presenter::stopwatch { auto frame_time = static_cast(time_diff.count()) / this->interval; auto fps = 1000.0 / frame_time; // 输出给用户 - std::print("FPS: {:.2f} Frame Time: {:.4f} ms\n", fps, frame_time); + spdlog::info("FPS: {:.2f} Frame Time: {:.4f} ms", fps, frame_time); // 把结束时间设置为开始时间继续下一轮循环 this->start_point = stop_point; diff --git a/BasaltPresenter/README.md b/BasaltPresenter/README.md index 3bc2dfb..9883db9 100644 --- a/BasaltPresenter/README.md +++ b/BasaltPresenter/README.md @@ -10,6 +10,8 @@ We assume that you executing following commands in the root directory of `Basalt ### spdlog +##### Build + ```sh cd external git clone -b 1.17.0 https://github.com/gabime/spdlog.git @@ -19,53 +21,65 @@ mkdir out cd out mkdir build mkdir install +cd build ``` In Windows: ```bat -cmake -A x64 ../.. +cmake -A x64 -DCMAKE_CXX_STANDARD=23 -DSPDLOG_WCHAR_SUPPORT=ON -DSPDLOG_WCHAR_FILENAMES=ON -DSPDLOG_WCHAR_CONSOLE=ON -DSPDLOG_BUILD_EXAMPLE=OFF ../.. cmake --build . --config Release -cmake --install . --prefix=../install +cmake --install . --config Release --prefix=../install ``` Or in POSIX: ```sh -cmake -DCMAKE_BUILD_TYPE=Release ../.. +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=23 -DSPDLOG_BUILD_EXAMPLE=OFF ../.. cmake --build . cmake --install . --prefix=../install ``` +##### Usage + +Use `-Dspdlog_ROOT=` in cmake when you configure this project. + #### tinyobjloader +##### Build + ```sh cd external -git clone -b v2.0.0 https://github.com/tinyobjloader/tinyobjloader.git +git clone -b v1.0.6 https://github.com/tinyobjloader/tinyobjloader.git cd tinyobjloader mkdir out cd out mkdir build mkdir install +cd build ``` In Windows: ```bat -cmake -A x64 ../.. +cmake -A x64 -DCMAKE_CXX_STANDARD=23 ../.. cmake --build . --config Release -cmake --install . --prefix=../install +cmake --install . --config Release --prefix=../install ``` Or in POSIX: ```sh -cmake -DCMAKE_BUILD_TYPE=Release ../.. +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=23 ../.. cmake --build . cmake --install . --prefix=../install ``` +##### Usage + +Use `-Dtinyobjloader_ROOT=` in cmake when you configure this project. + ## Warning This project was not written robustly. diff --git a/BasaltPresenter/Shared/CMakeLists.txt b/BasaltPresenter/Shared/CMakeLists.txt index d97b7f6..5891cda 100644 --- a/BasaltPresenter/Shared/CMakeLists.txt +++ b/BasaltPresenter/Shared/CMakeLists.txt @@ -30,6 +30,10 @@ PUBLIC "$" "$" ) +target_link_libraries(BasaltShared +PUBLIC + spdlog::spdlog +) target_compile_definitions(BasaltShared PUBLIC $<$:BASALT_OS_WINDOWS> diff --git a/BasaltPresenter/Shared/basalt/object_loader.cpp b/BasaltPresenter/Shared/basalt/object_loader.cpp index 9d92277..cfb5fd8 100644 --- a/BasaltPresenter/Shared/basalt/object_loader.cpp +++ b/BasaltPresenter/Shared/basalt/object_loader.cpp @@ -37,8 +37,9 @@ namespace basalt::shared::object_loader { IObjectLoader::~IObjectLoader() {} - void IObjectLoader::load() { + void IObjectLoader::load(ObjectLoaderConfig&& config) { if (this->status != ObjectLoaderStatus::Ready) throw std::runtime_error("unexpected object loader status"); + this->config = std::move(config); this->status = ObjectLoaderStatus::Loaded; } diff --git a/BasaltPresenter/Shared/basalt/object_loader.hpp b/BasaltPresenter/Shared/basalt/object_loader.hpp index 1e83fc0..7500323 100644 --- a/BasaltPresenter/Shared/basalt/object_loader.hpp +++ b/BasaltPresenter/Shared/basalt/object_loader.hpp @@ -1,6 +1,7 @@ #pragma once #include "math.hpp" #include +#include namespace basalt::shared::object_loader { @@ -20,6 +21,10 @@ namespace basalt::shared::object_loader { std::vector triangles; }; + struct ObjectLoaderConfig { + std::string filename; + }; + enum class ObjectLoaderStatus { Ready, Loaded, @@ -37,12 +42,13 @@ namespace basalt::shared::object_loader { virtual ~IObjectLoader(); public: - virtual void load(); + virtual void load(ObjectLoaderConfig&& config); const Object& get_object(size_t index) const; size_t get_object_count() const; protected: ObjectLoaderStatus status; + ObjectLoaderConfig config; std::vector objects; };