#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 new DirectX11Engine(); } BS_EXPORT void BSDestroyInstance(void* instance) { delete reinterpret_cast(instance); }