diff --git a/MVS/D3D12/main.cpp b/MVS/D3D12/main.cpp index c2dc0349..f129f517 100644 --- a/MVS/D3D12/main.cpp +++ b/MVS/D3D12/main.cpp @@ -17,21 +17,36 @@ #pragma comment(lib,"d3dcompiler.lib") #pragma comment(lib,"winmm.lib") +//================================================================================= +// D3D12 核心全局对象 (最小渲染所需) +//================================================================================= ID3D12Device* gD3D12Device = nullptr; ID3D12CommandQueue* gCommandQueue = nullptr; IDXGISwapChain3* gSwapChain = nullptr; -ID3D12Resource* gDSRT = nullptr, * gColorRTs[2]; + +// 渲染目标 (SwapChain的后台Buffer) +ID3D12Resource* gDSRT = nullptr; // 深度模板缓冲 +ID3D12Resource* gColorRTs[2]; // 颜色缓冲 (双缓冲) int gCurrentRTIndex = 0; -ID3D12DescriptorHeap* gSwapChainRTVHeap = nullptr; -ID3D12DescriptorHeap* gSwapChainDSVHeap = nullptr; + +// 描述符堆 +ID3D12DescriptorHeap* gSwapChainRTVHeap = nullptr; // RTV堆 +ID3D12DescriptorHeap* gSwapChainDSVHeap = nullptr; // DSV堆 UINT gRTVDescriptorSize = 0; UINT gDSVDescriptorSize = 0; + +// 命令相关 ID3D12CommandAllocator* gCommandAllocator = nullptr; ID3D12GraphicsCommandList* gCommandList = nullptr; + +// 同步对象 ID3D12Fence* gFence = nullptr; HANDLE gFenceEvent = nullptr; UINT64 gFenceValue = 0; +//================================================================================= +// 工具函数前向声明 +//================================================================================= D3D12_RESOURCE_BARRIER InitResourceBarrier( ID3D12Resource* inResource, D3D12_RESOURCE_STATES inPrevState, D3D12_RESOURCE_STATES inNextState); @@ -39,6 +54,9 @@ D3D12_RESOURCE_BARRIER InitResourceBarrier( ID3D12Resource* CreateBufferObject(ID3D12GraphicsCommandList* inCommandList, void* inData, int inDataLen, D3D12_RESOURCE_STATES inFinalResourceState); +//================================================================================= +// 工具函数 +//================================================================================= float srandom() { float number = float(rand()) / float(RAND_MAX); number *= 2.0f; @@ -46,18 +64,26 @@ float srandom() { return number; } +//================================================================================= +// 数据结构定义 +//================================================================================= struct StaticMeshComponentVertexData { float mPosition[4]; float mTexcoord[4]; float mNormal[4]; float mTangent[4]; }; + struct SubMesh { ID3D12Resource* mIBO; D3D12_INDEX_BUFFER_VIEW mIBView; int mIndexCount; }; +//================================================================================= +// 网格组件类 (StaticMeshComponent) +// 封装顶点缓冲(VBO)、索引缓冲(IBO)和渲染逻辑 +//================================================================================= class StaticMeshComponent { public: ID3D12Resource* mVBO; @@ -154,6 +180,10 @@ public: } }; +//================================================================================= +// ResourceBarrier 工具函数 +// 用于资源状态转换 (例如: PRESENT → RENDER_TARGET) +//================================================================================= D3D12_RESOURCE_BARRIER InitResourceBarrier( ID3D12Resource* inResource, D3D12_RESOURCE_STATES inPrevState, D3D12_RESOURCE_STATES inNextState) { @@ -168,6 +198,10 @@ D3D12_RESOURCE_BARRIER InitResourceBarrier( return d3d12ResourceBarrier; } +//================================================================================= +// 根签名初始化 (RootSignature) +// 定义GPU资源绑定规则: CBV(常量缓冲) / SRV(着色器资源) / DescriptorTable +//================================================================================= ID3D12RootSignature* InitRootSignature() { D3D12_ROOT_PARAMETER rootParameters[4]; rootParameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; @@ -227,6 +261,10 @@ ID3D12RootSignature* InitRootSignature() { return d3d12RootSignature; } +//================================================================================= +// 着色器加载函数 +// 从.hlsl文件编译着色器 (VS/GS/PS) +//================================================================================= void CreateShaderFromFile( LPCTSTR inShaderFilePath, const char* inMainFunctionName, @@ -248,6 +286,10 @@ void CreateShaderFromFile( inShader->BytecodeLength = shaderBuffer->GetBufferSize(); } +//================================================================================= +// 常量缓冲 (Constant Buffer) 创建与更新 +// UPLOAD堆: CPU可写, GPU可读 +//================================================================================= ID3D12Resource* CreateConstantBufferObject(int inDataLen) { D3D12_HEAP_PROPERTIES d3dHeapProperties = {}; d3dHeapProperties.Type = D3D12_HEAP_TYPE_UPLOAD; @@ -276,6 +318,9 @@ ID3D12Resource* CreateConstantBufferObject(int inDataLen) { return bufferObject; } +//================================================================================= +// 更新常量缓冲数据 +//================================================================================= void UpdateConstantBuffer(ID3D12Resource* inCB, void* inData, int inDataLen) { D3D12_RANGE d3d12Range = { 0 }; unsigned char* pBuffer = nullptr; @@ -284,6 +329,10 @@ void UpdateConstantBuffer(ID3D12Resource* inCB, void* inData, int inDataLen) { inCB->Unmap(0, nullptr); } +//================================================================================= +// GPU Buffer创建 (顶点/索引缓冲) +// DEFAULT堆 → 通过Upload堆中转数据 → 状态转换 +//================================================================================= ID3D12Resource* CreateBufferObject(ID3D12GraphicsCommandList* inCommandList, void* inData, int inDataLen, D3D12_RESOURCE_STATES inFinalResourceState) { D3D12_HEAP_PROPERTIES d3dHeapProperties = {}; @@ -344,6 +393,10 @@ ID3D12Resource* CreateBufferObject(ID3D12GraphicsCommandList* inCommandList, return bufferObject; } +//================================================================================= +// 2D纹理创建 +// DEFAULT堆 → 通过Upload堆中转数据 → CopyTextureRegion → 状态转换 +//================================================================================= ID3D12Resource* CreateTexture2D(ID3D12GraphicsCommandList* inCommandList, const void* inPixelData, int inDataSizeInBytes, int inWidth, int inHeight, DXGI_FORMAT inFormat) { @@ -429,6 +482,10 @@ ID3D12Resource* CreateTexture2D(ID3D12GraphicsCommandList* inCommandList, return texture; } +//================================================================================= +// 渲染管线状态对象 (PSO) +// 包含: InputLayout / VS/GS/PS / Rasterizer / DepthStencil / Blend +//================================================================================= ID3D12PipelineState* CreatePSO(ID3D12RootSignature* inID3D12RootSignature, D3D12_SHADER_BYTECODE inVertexShader, D3D12_SHADER_BYTECODE inPixelShader, D3D12_SHADER_BYTECODE inGSShader) { @@ -483,6 +540,20 @@ ID3D12PipelineState* CreatePSO(ID3D12RootSignature* inID3D12RootSignature, return d3d12PSO; } +//================================================================================= +// D3D12 初始化核心函数 (InitD3D12) +// 最小渲染系统初始化流程: +// 1. 启用Debug层 (可选, _DEBUG) +// 2. 创建IDXGIFactory4 +// 3. 枚举Adapter, 创建ID3D12Device +// 4. 创建CommandQueue (命令队列) +// 5. 创建SwapChain (交换链) +// 6. 创建DepthStencilBuffer (深度缓冲) +// 7. 创建RTV/DSV描述符堆 +// 8. 创建RenderTargetView / DepthStencilView +// 9. 创建CommandAllocator / CommandList +// 10. 创建Fence (同步) +//================================================================================= bool InitD3D12(HWND inHWND, int inWidth, int inHeight) { HRESULT hResult; UINT dxgiFactoryFlags = 0; @@ -607,6 +678,9 @@ bool InitD3D12(HWND inHWND, int inWidth, int inHeight) { return true; } +//================================================================================= +// 命令相关辅助函数 +//================================================================================= ID3D12CommandAllocator* GetCommandAllocator() { return gCommandAllocator; } @@ -622,6 +696,10 @@ void WaitForCompletionOfCommandList() { } } +//================================================================================= +// 命令列表结束提交 +// 关闭CommandList → ExecuteCommandLists → Signal Fence +//================================================================================= void EndCommandList() { gCommandList->Close(); ID3D12CommandList* ppCommandLists[] = { gCommandList }; @@ -630,6 +708,14 @@ void EndCommandList() { gCommandQueue->Signal(gFence, gFenceValue); } +//================================================================================= +// 开始渲染到SwapChain +// 1. 获取当前BackBuffer索引 +// 2. 状态转换: PRESENT → RENDER_TARGET +// 3. 设置RenderTargets (Color + Depth) +// 4. 设置Viewport/Scissor +// 5. Clear Color/Depth +//================================================================================= void BeginRenderToSwapChain(ID3D12GraphicsCommandList* inCommandList) { gCurrentRTIndex = gSwapChain->GetCurrentBackBufferIndex(); D3D12_RESOURCE_BARRIER barrier = InitResourceBarrier(gColorRTs[gCurrentRTIndex], D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET); @@ -647,21 +733,37 @@ void BeginRenderToSwapChain(ID3D12GraphicsCommandList* inCommandList) { inCommandList->ClearDepthStencilView(dsv, D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, 1.0f, 0, 0, nullptr); } +//================================================================================= +// 结束渲染到SwapChain +// 状态转换: RENDER_TARGET → PRESENT +//================================================================================= void EndRenderToSwapChain(ID3D12GraphicsCommandList* inCommandList) { D3D12_RESOURCE_BARRIER barrier = InitResourceBarrier(gColorRTs[gCurrentRTIndex], D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT); inCommandList->ResourceBarrier(1, &barrier); } +//================================================================================= +// 交换缓冲区 (显示渲染结果) +//================================================================================= void SwapD3D12Buffers() { gSwapChain->Present(0, 0); } +//================================================================================= +// 获取D3D12设备 +//================================================================================= ID3D12Device* GetD3DDevice() { return gD3D12Device; } +//================================================================================= +// Win32 窗口相关 +//================================================================================= LPCTSTR gWindowClassName = L"BattleFire"; +//================================================================================= +// 窗口消息回调函数 +//================================================================================= LRESULT CALLBACK WindowProc(HWND inHWND, UINT inMSG, WPARAM inWParam, LPARAM inLParam) { switch (inMSG) { case WM_CLOSE: @@ -671,6 +773,10 @@ LRESULT CALLBACK WindowProc(HWND inHWND, UINT inMSG, WPARAM inWParam, LPARAM inL return DefWindowProc(inHWND, inMSG, inWParam, inLParam); } +//================================================================================= +// 主入口函数 WinMain +// 程序入口点 +//================================================================================= int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int inShowCmd) { WNDCLASSEX wndClassEx; wndClassEx.cbSize = sizeof(WNDCLASSEX);