1
0

add device enumeration for dx11

This commit is contained in:
2026-01-10 21:35:59 +08:00
parent b96c1d4318
commit ab79440adc
4 changed files with 68 additions and 30 deletions

View File

@@ -1,16 +1,22 @@
#include <basalt/char_types.hpp>
#include <basalt/export_macro.hpp>
#include <basalt/engine.hpp>
#include <basalt/object_loader.hpp>
#include <basalt/anime_loader.hpp>
#include <spdlog/spdlog.h>
#include <windows.h>
#include <d3d11.h>
#include <d3dcompiler.h>
#include <wrl/client.h>
#include <vector>
#include <iostream>
#include <cmath>
#include <print>
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<IDXGIFactory> factory; ///< 适配器工厂
ComPtr<IDXGIAdapter> adapter; ///< 适配器
ComPtr<ID3D11Device> device; ///< 设备
ComPtr<ID3D11DeviceContext> context; ///< 上下文
ComPtr<IDXGISwapChain> swap_chain; ///< 交换链
@@ -151,21 +159,6 @@ private:
public:
virtual guid::Guid get_guid() const { return guid::DIRECTX11_ENGINE; }
//virtual void enumerate_devices() override {
// ComPtr<IDXGIFactory> factory;
// ComPtr<IDXGIAdapter> 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<UINT>(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<IDXGIDevice> dxgi_device;
DXCHK(device.As(&dxgi_device));
ComPtr<IDXGIAdapter> adapter;
DXCHK(dxgi_device->GetAdapter(&adapter));
ComPtr<IDXGIFactory> factory;
DXCHK(adapter->GetParent(IID_PPV_ARGS(&factory)));
DXCHK(factory->CreateSwapChain(device.Get(), &sd, &swap_chain));
// 创建渲染目标
@@ -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);

View File

@@ -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};

View File

@@ -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.

View File

@@ -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",