From a66d3dee8b75e4b3abe9fc4f25e495e9e78f76dc Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Sun, 4 Jan 2026 17:16:54 +0800 Subject: [PATCH] add some AI generated dx11 render code --- BasaltPresenter/CMakeLists.txt | 6 +- .../Plugins/Deliver/CMakeLists.txt | 20 +- BasaltPresenter/Plugins/Engine/CMakeLists.txt | 24 +- .../Engine/DirectX11Engine/CMakeLists.txt | 1 + .../Plugins/Engine/DirectX11Engine/main.cpp | 228 +++++++++++++++++- BasaltPresenter/Shared/engine.cpp | 24 +- BasaltPresenter/Shared/engine.hpp | 13 +- 7 files changed, 297 insertions(+), 19 deletions(-) diff --git a/BasaltPresenter/CMakeLists.txt b/BasaltPresenter/CMakeLists.txt index ccd5198..bf42bc0 100644 --- a/BasaltPresenter/CMakeLists.txt +++ b/BasaltPresenter/CMakeLists.txt @@ -35,13 +35,15 @@ set(CMAKE_CXX_EXTENSIONS OFF) # Include some essential CMake components include(GNUInstallDirs) -# Import packages # Find required packages based on options +set(CMAKE_MODULE_PATH + "${CMAKE_CURRENT_LIST_DIR}/CMake" +) if (BASALT_CUDA_DELIVER) find_package(CUDA REQUIRED) endif () if (BASALT_DIRECTX11_ENGINE) - include(cmake/FindDirectX11.cmake) + find_package(DirectX11 REQUIRED) endif () diff --git a/BasaltPresenter/Plugins/Deliver/CMakeLists.txt b/BasaltPresenter/Plugins/Deliver/CMakeLists.txt index 0519942..ae5021d 100644 --- a/BasaltPresenter/Plugins/Deliver/CMakeLists.txt +++ b/BasaltPresenter/Plugins/Deliver/CMakeLists.txt @@ -1,5 +1,15 @@ -# add_subdirectory(CudaDeliver) -# add_subdirectory(RocmDeliver) -add_subdirectory(PipeDeliver) -# add_subdirectory(TcpDeliver) -# add_subdirectory(MmapDeliver) +# if (BASALT_CUDA_DELIVER) +# add_subdirectory(CudaDeliver) +# endif () +# if (BASALT_ROCM_DELIVER) +# add_subdirectory(RocmDeliver) +# endif () +if (BASALT_PIPE_DELIVER) + add_subdirectory(PipeDeliver) +endif () +# if (BASALT_TCP_DELIVER) +# add_subdirectory(TcpDeliver) +# endif () +# if (BASALT_MMAP_DELIVER) +# add_subdirectory(MmapDeliver) +# endif () diff --git a/BasaltPresenter/Plugins/Engine/CMakeLists.txt b/BasaltPresenter/Plugins/Engine/CMakeLists.txt index 7112de5..b9a1a5f 100644 --- a/BasaltPresenter/Plugins/Engine/CMakeLists.txt +++ b/BasaltPresenter/Plugins/Engine/CMakeLists.txt @@ -1,6 +1,18 @@ -# add_subdirectory(DirectX8Engine) -# add_subdirectory(DirectX9Engine) -add_subdirectory(DirectX11Engine) -# add_subdirectory(DirectX12Engine) -# add_subdirectory(OpenGLEngine) -# add_subdirectory(VulkanEngine) +# if (BASALT_DIRECTX8_ENGINE) +# add_subdirectory(DirectX8Engine) +# endif () +# if (BASALT_DIRECTX9_ENGINE) +# add_subdirectory(DirectX9Engine) +# endif () +if (BASALT_DIRECTX11_ENGINE) + add_subdirectory(DirectX11Engine) +endif () +# if (BASALT_DIRECTX12_ENGINE) +# add_subdirectory(DirectX12Engine) +# endif () +# if (BASALT_OPENGL_ENGINE) +# add_subdirectory(OpenGLEngine) +# endif () +# if (BASALT_VULKAN_ENGINE) +# add_subdirectory(VulkanEngine) +# endif () diff --git a/BasaltPresenter/Plugins/Engine/DirectX11Engine/CMakeLists.txt b/BasaltPresenter/Plugins/Engine/DirectX11Engine/CMakeLists.txt index 573c665..eb9a26a 100644 --- a/BasaltPresenter/Plugins/Engine/DirectX11Engine/CMakeLists.txt +++ b/BasaltPresenter/Plugins/Engine/DirectX11Engine/CMakeLists.txt @@ -14,6 +14,7 @@ PRIVATE target_link_libraries(DirectX11Engine PRIVATE BasaltShared + ${DirectX11_LIBRARY} ) # Enable export macro target_compile_definitions(DirectX11Engine diff --git a/BasaltPresenter/Plugins/Engine/DirectX11Engine/main.cpp b/BasaltPresenter/Plugins/Engine/DirectX11Engine/main.cpp index 734b6b9..57c27ba 100644 --- a/BasaltPresenter/Plugins/Engine/DirectX11Engine/main.cpp +++ b/BasaltPresenter/Plugins/Engine/DirectX11Engine/main.cpp @@ -1,9 +1,233 @@ #include +#include +#include +#include +#include +#include +#include +#include + +using Microsoft::WRL::ComPtr; + +// 常量 +constexpr UINT Width = 800; +constexpr UINT Height = 600; +constexpr const wchar_t* PipeName = L"\\\\.\\pipe\\54da494c-301a-47a9-9d67-4fbebaeda8cf"; + +// 立方体顶点(位置) +struct Vertex { + float x, y, z; +}; +Vertex CubeVertices[] = { + // 前面 + {-1, -1, -1}, + {1, -1, -1}, + {1, 1, -1}, + {-1, -1, -1}, + {1, 1, -1}, + {-1, 1, -1}, + // 后面 + {-1, -1, 1}, + {-1, 1, 1}, + {1, 1, 1}, + {-1, -1, 1}, + {1, 1, 1}, + {1, -1, 1}, + // 其他面...(为简化,此处略,或用完整立方体) + // 实际建议使用完整12个三角面(36顶点) +}; +// 为简化,这里只渲染前面,实际请补全 + +// 简单顶点着色器(只传位置) +const char* g_VS = R"( + float4 main(float3 pos : POSITION) : SV_POSITION { + return float4(pos, 1.0f); + } +)"; + +// 简单像素着色器(返回固定颜色) +const char* g_PS = R"( + float4 main() : SV_TARGET { + return float4(0.2f, 0.4f, 0.8f, 1.0f); + } +)"; + +int main() { + // 初始化 COM + CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + + // 创建设备和上下文 + ComPtr device; + ComPtr context; + D3D11CreateDevice( + nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, D3D11_CREATE_DEVICE_DEBUG, nullptr, 0, D3D11_SDK_VERSION, &device, nullptr, &context); + + // 创建交换链(窗口可选,这里仅用于渲染上下文) + ComPtr swapChain; + DXGI_SWAP_CHAIN_DESC sd = {}; + sd.BufferDesc.Width = Width; + sd.BufferDesc.Height = Height; + sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + sd.SampleDesc.Count = 1; + sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + sd.BufferCount = 1; + sd.OutputWindow = GetConsoleWindow(); // 或创建窗口 + sd.Windowed = TRUE; + + ComPtr dxgiDevice; + device.As(&dxgiDevice); + ComPtr adapter; + dxgiDevice->GetAdapter(&adapter); + ComPtr factory; + adapter->GetParent(IID_PPV_ARGS(&factory)); + factory->CreateSwapChain(device.Get(), &sd, &swapChain); + + // 创建渲染目标 + ComPtr rtv; + ComPtr backBuffer; + swapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer)); + device->CreateRenderTargetView(backBuffer.Get(), nullptr, &rtv); + + // 创建深度缓冲(D32_FLOAT) + ComPtr depthBuffer; + D3D11_TEXTURE2D_DESC depthDesc = {}; + depthDesc.Width = Width; + depthDesc.Height = Height; + depthDesc.MipLevels = 1; + depthDesc.ArraySize = 1; + depthDesc.Format = DXGI_FORMAT_D32_FLOAT; + depthDesc.SampleDesc.Count = 1; + depthDesc.Usage = D3D11_USAGE_DEFAULT; + depthDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; + device->CreateTexture2D(&depthDesc, nullptr, &depthBuffer); + + ComPtr dsv; + device->CreateDepthStencilView(depthBuffer.Get(), nullptr, &dsv); + + // 创建 staging texture 用于 CPU 读取深度(R32_FLOAT) + ComPtr depthStaging; + D3D11_TEXTURE2D_DESC stagingDesc = depthDesc; + stagingDesc.Format = DXGI_FORMAT_R32_FLOAT; // 注意:DSV 用 D32_FLOAT,staging 用 R32_FLOAT + stagingDesc.BindFlags = 0; + stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + stagingDesc.Usage = D3D11_USAGE_STAGING; + device->CreateTexture2D(&stagingDesc, nullptr, &depthStaging); + + // 编译并创建着色器 + ComPtr vs; + ComPtr ps; + ComPtr vsBlob, psBlob; + D3DCompile(g_VS, strlen(g_VS), nullptr, nullptr, nullptr, "main", "vs_4_0", 0, 0, &vsBlob, nullptr); + D3DCompile(g_PS, strlen(g_PS), nullptr, nullptr, nullptr, "main", "ps_4_0", 0, 0, &psBlob, nullptr); + device->CreateVertexShader(vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), nullptr, &vs); + device->CreatePixelShader(psBlob->GetBufferPointer(), psBlob->GetBufferSize(), nullptr, &ps); + + // 输入布局 + D3D11_INPUT_ELEMENT_DESC layout[] = {{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}}; + ComPtr inputLayout; + device->CreateInputLayout(layout, 1, vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), &inputLayout); + + // 顶点缓冲 + ComPtr vertexBuffer; + D3D11_BUFFER_DESC vbDesc = {}; + vbDesc.ByteWidth = sizeof(CubeVertices); + vbDesc.Usage = D3D11_USAGE_DEFAULT; + vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + D3D11_SUBRESOURCE_DATA vbData = {CubeVertices}; + device->CreateBuffer(&vbDesc, &vbData, &vertexBuffer); + + // 深度测试启用 + ComPtr depthState; + D3D11_DEPTH_STENCIL_DESC dsDesc = {}; + dsDesc.DepthEnable = TRUE; + dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + dsDesc.DepthFunc = D3D11_COMPARISON_LESS; + device->CreateDepthStencilState(&dsDesc, &depthState); + + // 视口 + D3D11_VIEWPORT vp = {0, 0, (float) Width, (float) Height, 0, 1}; + context->RSSetViewports(1, &vp); + + // 打开命名管道(需另一进程已创建) + HANDLE hPipe = CreateFileW(PipeName, GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr); + + if (hPipe == INVALID_HANDLE_VALUE) { + std::cerr << "Failed to open named pipe. Ensure another process created it.\n"; + return -1; + } + + constexpr size_t depthSize = Width * Height * sizeof(float); + std::vector depthData(depthSize); + + // 渲染循环(示例只渲染10帧) + for (int frame = 0; frame < 10; ++frame) { + // 清屏 + float clearColor[] = {0.1f, 0.1f, 0.1f, 1.0f}; + context->ClearRenderTargetView(rtv.Get(), clearColor); + context->ClearDepthStencilView(dsv.Get(), D3D11_CLEAR_DEPTH, 1.0f, 0); + + // 设置管线 + context->OMSetRenderTargets(1, rtv.GetAddressOf(), dsv.Get()); + context->OMSetDepthStencilState(depthState.Get(), 1); + context->VSSetShader(vs.Get(), nullptr, 0); + context->PSSetShader(ps.Get(), nullptr, 0); + context->IASetInputLayout(inputLayout.Get()); + UINT stride = sizeof(Vertex), offset = 0; + context->IASetVertexBuffers(0, 1, vertexBuffer.GetAddressOf(), &stride, &offset); + context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + // 绘制立方体 + context->Draw(6, 0); // 仅前面,实际应为36 + + // 复制深度缓冲到 staging texture + context->CopyResource(depthStaging.Get(), depthBuffer.Get()); + + // Map 获取数据 + D3D11_MAPPED_SUBRESOURCE mapped; + context->Map(depthStaging.Get(), 0, D3D11_MAP_READ, 0, &mapped); + memcpy(depthData.data(), mapped.pData, depthSize); + context->Unmap(depthStaging.Get(), 0); + + // 写入命名管道 + DWORD written; + if (!WriteFile(hPipe, depthData.data(), static_cast(depthSize), &written, nullptr) || written != depthSize) { + std::cerr << "WriteFile failed or incomplete.\n"; + break; + } + + // 呈现(可选) + swapChain->Present(0, 0); + } + + CloseHandle(hPipe); + CoUninitialize(); + return 0; +} + +using ::Basalt::Shared::Engine::EngineConfig; +using ::Basalt::Shared::Engine::IEngine; + +class DirectX11Engine : public IEngine { +public: + DirectX11Engine() : IEngine() {} + virtual ~DirectX11Engine() {} + +private: + ComPtr device; ///< 设备 + ComPtr context; ///< 上下文 + ComPtr swapChain; ///< 交换链 + + +public: + virtual void Startup(EngineConfig&& config) override { IEngine::Startup(std::move(config)); } + virtual void Tick() override { IEngine::Tick(); } + virtual void Shutdown() override { IEngine::Shutdown(); } +}; BS_EXPORT void* BSCreateInstance() { - return nullptr; + return new DirectX11Engine(); } BS_EXPORT void BSDestroyInstance(void* instance) { - return; + delete reinterpret_cast(instance); } diff --git a/BasaltPresenter/Shared/engine.cpp b/BasaltPresenter/Shared/engine.cpp index 8f238a4..6a7d8bc 100644 --- a/BasaltPresenter/Shared/engine.cpp +++ b/BasaltPresenter/Shared/engine.cpp @@ -1,9 +1,29 @@ #include "engine.hpp" +#include namespace Basalt::Shared::Engine { - IEngine::IEngine(EngineConfig&& config) : config(std::move(config)) {} + IEngine::IEngine() : config(), status(EngineStatus::Ready) {} - IEngine::~IEngine() {} + IEngine::~IEngine() { + if (this->status != EngineStatus::Stop) { + this->Shutdown(); + } + } + + void IEngine::Startup(EngineConfig &&config) { + if (this->status != EngineStatus::Ready) throw std::runtime_error("unexpected engine status"); + this->config = std::move(config); + this->status = EngineStatus::Running; + } + + void IEngine::Tick() { + if (this->status != EngineStatus::Running) throw std::runtime_error("unexpected engine status"); + } + + void IEngine::Shutdown() { + if (this->status != EngineStatus::Running) throw std::runtime_error("unexpected engine status"); + this->status = EngineStatus::Stop; + } } // namespace Basalt::Shared::Engine diff --git a/BasaltPresenter/Shared/engine.hpp b/BasaltPresenter/Shared/engine.hpp index 625f564..e172d0a 100644 --- a/BasaltPresenter/Shared/engine.hpp +++ b/BasaltPresenter/Shared/engine.hpp @@ -21,16 +21,25 @@ namespace Basalt::Shared::Engine { std::uint32_t height; ///< Window height. }; + enum class EngineStatus { + Ready, ///< Engine was allocated but not initialized. + Running, ///< Engine has been initialized and running. + Stop, ///< Engine is shutdown. + }; + class IEngine { public: - IEngine(EngineConfig&& config); + IEngine(); virtual ~IEngine(); public: - virtual void Tick() = 0; + virtual void Startup(EngineConfig&& config); + virtual void Tick(); + virtual void Shutdown(); protected: EngineConfig config; + EngineStatus status; }; }