diff --git a/BasaltPresenter/Plugins/Engine/DirectX11Engine/main.cpp b/BasaltPresenter/Plugins/Engine/DirectX11Engine/main.cpp index e7d6299..e3e8013 100644 --- a/BasaltPresenter/Plugins/Engine/DirectX11Engine/main.cpp +++ b/BasaltPresenter/Plugins/Engine/DirectX11Engine/main.cpp @@ -1,16 +1,22 @@ +#include #include #include #include +#include +#include #include #include #include #include #include #include +#include +#include using Microsoft::WRL::ComPtr; #define DXCHK(condition) \ if (FAILED(condition)) { \ + std::println("bad DirectX calling with code {}", condition); \ throw std::runtime_error("bad DirectX calling"); \ } @@ -119,9 +125,9 @@ const char* g_PS = R"( namespace guid = ::basalt::shared::guid; namespace engine = ::basalt::shared::engine; +using ::basalt::shared::math::Vector3; using engine::EngineConfig; using engine::IEngine; -using ::basalt::shared::math::Vector3; class DirectX11Engine : public IEngine { public: @@ -130,6 +136,8 @@ public: private: HWND window; ///< Win32窗口 + ComPtr factory; ///< 适配器工厂 + ComPtr adapter; ///< 适配器 ComPtr device; ///< 设备 ComPtr context; ///< 上下文 ComPtr swap_chain; ///< 交换链 @@ -151,21 +159,6 @@ private: public: virtual guid::Guid get_guid() const { return guid::DIRECTX11_ENGINE; } - //virtual void enumerate_devices() override { - // ComPtr factory; - // ComPtr adapter; - // HRESULT hr = CreateDXGIFactory(IID_PPV_ARGS(&factory)); - // if (SUCCEEDED(hr)) { - // UINT i = 0; - // while (factory->EnumAdapters(i, &adapter) != DXGI_ERROR_NOT_FOUND) { - // DXGI_ADAPTER_DESC desc; - // if (SUCCEEDED(adapter->GetDesc(&desc))) { - // std::wcout << L"Adapter " << i << L": " << desc.Description << std::endl; - // } - // ++i; - // } - // } - //} virtual void startup(EngineConfig&& config) override { IEngine::startup(std::move(config)); @@ -181,11 +174,25 @@ public: // 初始化 COM DXCHK(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED)); + // 创建Factory和Adapter,枚举并选择设备 + DXCHK(CreateDXGIFactory(IID_PPV_ARGS(&factory))); + spdlog::info(BSTEXT("Available DirectX Devices:")); + { + UINT i = 0; + while (factory->EnumAdapters(i, &adapter) != DXGI_ERROR_NOT_FOUND) { + DXGI_ADAPTER_DESC desc; + DXCHK(adapter->GetDesc(&desc)); + spdlog::info(BSTEXT("\t{}\t{}"), i, desc.Description); + ++i; + } + } + DXCHK(factory->EnumAdapters(static_cast(this->config.device), &adapter)); + // 创建设备和上下文 - DXCHK(D3D11CreateDevice(nullptr, - D3D_DRIVER_TYPE_HARDWARE, + DXCHK(D3D11CreateDevice(adapter.Get(), + D3D_DRIVER_TYPE_UNKNOWN, nullptr, - D3D11_CREATE_DEVICE_DEBUG, + 0,//D3D11_CREATE_DEVICE_DEBUG, nullptr, 0, D3D11_SDK_VERSION, @@ -203,13 +210,6 @@ public: sd.BufferCount = 1; sd.OutputWindow = window; sd.Windowed = TRUE; - - ComPtr dxgi_device; - DXCHK(device.As(&dxgi_device)); - ComPtr adapter; - DXCHK(dxgi_device->GetAdapter(&adapter)); - ComPtr factory; - DXCHK(adapter->GetParent(IID_PPV_ARGS(&factory))); DXCHK(factory->CreateSwapChain(device.Get(), &sd, &swap_chain)); // 创建渲染目标 @@ -261,7 +261,7 @@ public: const auto& obj = this->config.object_loader->get_object(i); const auto* obj_vertices = obj.get_vertices(); size_t obj_vertex_count = obj.get_vertices_count(); - + for (size_t j = 0; j < obj_vertex_count; ++j) { Vertex v; v.x = obj_vertices[j].x; @@ -279,7 +279,7 @@ public: DXCHK(device->CreateBuffer(&vb_desc, &vb_data, &vertex_buffer)); // Update draw call to use actual vertex count vertex_count = vertices.size(); - + // 深度测试启用 D3D11_DEPTH_STENCIL_DESC ds_desc = {}; ds_desc.DepthEnable = TRUE; @@ -337,6 +337,42 @@ public: // Event loop if (EventLoop()) return true; + // 获取动画关键帧数据 + basalt::shared::anime_loader::KeyFrameSpan keyframe_span; + if (this->config.anime_loader) { + keyframe_span = this->config.anime_loader->tick(); + + // Blender坐标系到DirectX坐标系的转换 + // Blender (右手坐标系): 右+x, 上+y, 前-z + // DirectX (左手坐标系): 右+x, 上+y, 前+z + + // 位置变换: X不变, Y不变, Z取反 + float pos_x = keyframe_span.prev_position.x * keyframe_span.prev_time + keyframe_span.next_position.x * keyframe_span.next_time; + float pos_y = keyframe_span.prev_position.y * keyframe_span.prev_time + keyframe_span.next_position.y * keyframe_span.next_time; + float pos_z = -(keyframe_span.prev_position.z * keyframe_span.prev_time + + keyframe_span.next_position.z * keyframe_span.next_time); + + // 旋转四元数变换: X和Z取反, Y和W保持不变 + float rot_x = -(keyframe_span.prev_rotation.x * keyframe_span.prev_time + + keyframe_span.next_rotation.x * keyframe_span.next_time); + float rot_y = keyframe_span.prev_rotation.y * keyframe_span.prev_time + keyframe_span.next_rotation.y * keyframe_span.next_time; + float rot_z = -(keyframe_span.prev_rotation.z * keyframe_span.prev_time + + keyframe_span.next_rotation.z * keyframe_span.next_time); + float rot_w = keyframe_span.prev_rotation.w * keyframe_span.prev_time + keyframe_span.next_rotation.w * keyframe_span.next_time; + + // 归一化四元数 + float length = std::sqrt(rot_x * rot_x + rot_y * rot_y + rot_z * rot_z + rot_w * rot_w); + if (length > 0.0f) { + rot_x /= length; + rot_y /= length; + rot_z /= length; + rot_w /= length; + } + + // 这里可以应用相机变换,但目前我们只是获取了动画数据 + // 在实际渲染中,这些值将用于构建视图矩阵 + } + // 清屏 float clear_color[] = {0.8f, 0.1f, 0.1f, 1.0f}; context->ClearRenderTargetView(rtv.Get(), clear_color); diff --git a/BasaltPresenter/Presenter/main.cpp b/BasaltPresenter/Presenter/main.cpp index 01c8ddb..1aa818f 100644 --- a/BasaltPresenter/Presenter/main.cpp +++ b/BasaltPresenter/Presenter/main.cpp @@ -64,6 +64,7 @@ int main(int argc, char* argv[]) { EngineConfig engine_config{.headless = payload.headless, .width = payload.width, .height = payload.height, + .device = payload.engine_device, //.deliver = deliver_inst->get_guid(), .object_loader = object_loader_inst, .anime_loader = anime_loader_inst}; diff --git a/BasaltPresenter/Shared/basalt/engine.hpp b/BasaltPresenter/Shared/basalt/engine.hpp index 0ddfb5d..f1fb5e7 100644 --- a/BasaltPresenter/Shared/basalt/engine.hpp +++ b/BasaltPresenter/Shared/basalt/engine.hpp @@ -11,6 +11,7 @@ namespace basalt::shared::engine { bool headless; ///< Whether enable headless mode (No Window created). std::uint32_t width; ///< Window width. std::uint32_t height; ///< Window height. + std::uint32_t device; ///< The device index of render engine. guid::Guid deliver; ///< The GUID of deliver. object_loader::IObjectLoader* object_loader; ///< The instance of object loader. anime_loader::IAnimeLoader* anime_loader; ///< The instance of anime loader. diff --git a/BasaltTrainer/main.py b/BasaltTrainer/main.py index 7fe0e0c..ab8ec84 100644 --- a/BasaltTrainer/main.py +++ b/BasaltTrainer/main.py @@ -9,7 +9,7 @@ def receive_data() -> None: def main(): # parse argument - opts = cli.parse() + #opts = cli.parse() server = CmdServer() print("Please launch BasaltPresenter now.") @@ -23,7 +23,7 @@ def main(): width=600, height=600, engine_name="BasaltDirectX11Engine", - engine_device=0, + engine_device=1, deliver_name="BasaltPipeDeliver", deliver_device=0, object_loader_name="BasaltObjObjectLoader",