@@ -1,9 +1,233 @@
# include <basalt_export.hpp>
# include <engine.hpp>
# include <windows.h>
# include <d3d11.h>
# include <d3dcompiler.h>
# include <wrl/client.h>
# include <vector>
# include <iostream>
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 < ID3D11Device > device ;
ComPtr < ID3D11DeviceContext > context ;
D3D11CreateDevice (
nullptr , D3D_DRIVER_TYPE_HARDWARE , nullptr , D3D11_CREATE_DEVICE_DEBUG , nullptr , 0 , D3D11_SDK_VERSION , & device , nullptr , & context ) ;
// 创建交换链(窗口可选,这里仅用于渲染上下文)
ComPtr < IDXGISwapChain > 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 < IDXGIDevice > dxgiDevice ;
device . As ( & dxgiDevice ) ;
ComPtr < IDXGIAdapter > adapter ;
dxgiDevice - > GetAdapter ( & adapter ) ;
ComPtr < IDXGIFactory > factory ;
adapter - > GetParent ( IID_PPV_ARGS ( & factory ) ) ;
factory - > CreateSwapChain ( device . Get ( ) , & sd , & swapChain ) ;
// 创建渲染目标
ComPtr < ID3D11RenderTargetView > rtv ;
ComPtr < ID3D11Texture2D > backBuffer ;
swapChain - > GetBuffer ( 0 , IID_PPV_ARGS ( & backBuffer ) ) ;
device - > CreateRenderTargetView ( backBuffer . Get ( ) , nullptr , & rtv ) ;
// 创建深度缓冲( D32_FLOAT)
ComPtr < ID3D11Texture2D > 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 < ID3D11DepthStencilView > dsv ;
device - > CreateDepthStencilView ( depthBuffer . Get ( ) , nullptr , & dsv ) ;
// 创建 staging texture 用于 CPU 读取深度( R32_FLOAT)
ComPtr < ID3D11Texture2D > 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 < ID3D11VertexShader > vs ;
ComPtr < ID3D11PixelShader > ps ;
ComPtr < ID3DBlob > 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 < ID3D11InputLayout > inputLayout ;
device - > CreateInputLayout ( layout , 1 , vsBlob - > GetBufferPointer ( ) , vsBlob - > GetBufferSize ( ) , & inputLayout ) ;
// 顶点缓冲
ComPtr < ID3D11Buffer > 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 < ID3D11DepthStencilState > 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 < BYTE > 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 < DWORD > ( 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 < ID3D11Device > device ; ///< 设备
ComPtr < ID3D11DeviceContext > context ; ///< 上下文
ComPtr < IDXGISwapChain > 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 < DirectX11Engine * > ( instance ) ;
}