Files
XCEngine/MVS/XCEngineDemo/main.cpp
ssdfasd 3ad317afb2 feat: 修复RHI渲染循环问题
- 修复RootSignature参数数量与HelloEarth一致
- 修复StaticMeshComponent中device为nullptr的问题
- 修复CommandList::Reset类型转换问题
- 修复RTV创建使用nullptr而不是rtvDesc
- 添加SwapChain的GetCurrentRenderTarget方法
- 修复DepthStencil创建问题(暂时跳过)
- 渲染循环基本可运行
2026-03-14 03:13:10 +08:00

269 lines
8.8 KiB
C++

#include <windows.h>
#include <stdio.h>
#include <RHI\IRHIDevice.h>
#include <RHI\IRHIResources.h>
#include <Rendering\Resources.h>
#include <Rendering\RenderContext.h>
#include <Rendering\StaticMeshComponent.h>
#include <Rendering\Shader.h>
#include <RHI\D3D12\D3D12RHI.h>
#include <RHI\D3D12\D3D12Resources.h>
#pragma comment(lib,"d3d12.lib")
#pragma comment(lib,"dxgi.lib")
#pragma comment(lib,"d3dcompiler.lib")
#pragma comment(lib,"winmm.lib")
void EngineLog(const char* msg, ...);
using namespace XCEngine;
using namespace XCEngine::RHI;
LPCWSTR gWindowClassName = L"XCEngineDemo";
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_CLOSE:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hInstancePrev, LPWSTR lpCmdLine, int nShowCmd) {
AttachConsole(ATTACH_PARENT_PROCESS);
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
printf("=== XCEngine Demo Started ===\n");
printf("Registering window class...\n");
WNDCLASSEX wndClass = {};
wndClass.cbSize = sizeof(WNDCLASSEX);
wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.hInstance = hInstance;
wndClass.lpszClassName = gWindowClassName;
wndClass.lpfnWndProc = WindowProc;
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
if (!RegisterClassEx(&wndClass)) {
printf("RegisterClassEx failed!\n");
return -1;
}
printf("Window class registered\n");
printf("Creating window...\n");
int width = 1280;
int height = 720;
RECT rect = {0, 0, width, height};
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
HWND hwnd = CreateWindowExW(NULL, gWindowClassName, L"XCEngine Demo",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, hInstance, NULL);
if (!hwnd) {
printf("CreateWindowExW failed!\n");
return -1;
}
printf("Window created\n");
printf("Creating D3D12Device...\n");
D3D12Device* device = new D3D12Device();
if (!device->Initialize(hwnd, width, height)) {
printf("D3D12Device Init Failed!\n");
return -1;
}
printf("D3D12Device initialized\n");
RenderContext renderContext(device);
if (!renderContext.Initialize(width, height)) {
printf("RenderContext Init Failed!\n");
return -1;
}
ICommandList* cmdList = renderContext.GetCommandList();
ShaderBytecode vs, ps, gs = {};
if (!CompileShader("Res/Shader/gs.hlsl", "MainVS", "vs_5_1", vs)) {
printf("Compile VS Failed!\n");
return -1;
}
if (!CompileShader("Res/Shader/gs.hlsl", "MainPS", "ps_5_1", ps)) {
printf("Compile PS Failed!\n");
return -1;
}
if (!CompileShader("Res/Shader/gs.hlsl", "MainGS", "gs_5_1", gs)) {
printf("Compile GS Failed!\n");
return -1;
}
printf("Shaders compiled: VS=%llu, PS=%llu, GS=%llu\n",
(unsigned long long)vs.size, (unsigned long long)ps.size, (unsigned long long)gs.size);
RootParameter params[4] = {};
params[0].type = RootParameterType::CBV;
params[0].shaderRegister = 1;
params[0].registerSpace = 0;
params[0].visibility = ShaderVisibility::All;
params[1].type = RootParameterType::Constants;
params[1].shaderRegister = 0;
params[1].registerSpace = 0;
params[1].num32BitValues = 4;
params[1].visibility = ShaderVisibility::Vertex;
params[2].type = RootParameterType::DescriptorTable;
params[2].shaderRegister = 0;
params[2].registerSpace = 0;
params[2].visibility = ShaderVisibility::Pixel;
params[3].type = RootParameterType::SRV;
params[3].shaderRegister = 0;
params[3].registerSpace = 1;
params[3].visibility = ShaderVisibility::All;
RootSignatureDesc rsDesc = {};
rsDesc.parameters = params;
rsDesc.parameterCount = 4;
IRootSignature* rootSignature = nullptr;
if (!device->CreateRootSignature(&rootSignature, rsDesc)) {
printf("CreateRootSignature Failed!\n");
return -1;
}
printf("RootSignature created\n");
InputElementDesc inputElements[4] = {};
inputElements[0].semanticName = "POSITION";
inputElements[0].semanticIndex = 0;
inputElements[0].format = Format::R32G32B32A32_Float;
inputElements[0].inputSlot = 0;
inputElements[0].alignedByteOffset = 0;
inputElements[1].semanticName = "TEXCOORD";
inputElements[1].semanticIndex = 0;
inputElements[1].format = Format::R32G32B32A32_Float;
inputElements[1].inputSlot = 0;
inputElements[1].alignedByteOffset = 16;
inputElements[2].semanticName = "NORMAL";
inputElements[2].semanticIndex = 0;
inputElements[2].format = Format::R32G32B32A32_Float;
inputElements[2].inputSlot = 0;
inputElements[2].alignedByteOffset = 32;
inputElements[3].semanticName = "TANGENT";
inputElements[3].semanticIndex = 0;
inputElements[3].format = Format::R32G32B32A32_Float;
inputElements[3].inputSlot = 0;
inputElements[3].alignedByteOffset = 48;
InputLayoutDesc inputLayout = {};
inputLayout.elements = inputElements;
inputLayout.elementCount = 4;
PipelineDesc psoDesc = {};
psoDesc.rootSignature = rootSignature;
psoDesc.vertexShader = vs;
psoDesc.pixelShader = ps;
psoDesc.geometryShader = gs;
psoDesc.inputLayout = inputLayout;
psoDesc.topologyType = PrimitiveTopologyType::Triangle;
psoDesc.numRenderTargets = 1;
psoDesc.rtvFormats[0] = Format::R8G8B8A8_UNorm;
psoDesc.dsvFormat = Format::D24_UNorm_S8_UInt;
IPipelineState* pso = nullptr;
printf("Creating PipelineState...\n");
if (!device->CreatePipelineState(&pso, psoDesc)) {
printf("CreatePipelineState Failed!\n");
return -1;
}
printf("PipelineState created\n");
EngineLog("After PSO created");
IConstantBuffer* cb = nullptr;
if (!CreateConstantBuffer(device, 65536, &cb)) {
printf("CreateConstantBuffer Failed!\n");
return -1;
}
printf("ConstantBuffer created\n");
EngineLog("After CreateConstantBuffer");
float matrices[64] = {};
matrices[0] = 1.0f; matrices[5] = 1.0f; matrices[10] = 1.0f; matrices[15] = 1.0f;
matrices[16] = 1.0f; matrices[21] = 1.0f; matrices[26] = 1.0f; matrices[31] = 1.0f;
matrices[32] = 1.0f; matrices[37] = 1.0f; matrices[42] = 1.0f; matrices[47] = 1.0f;
matrices[48] = 1.0f; matrices[53] = 1.0f; matrices[58] = 1.0f; matrices[63] = 1.0f;
UpdateConstantBuffer(cb, matrices, sizeof(matrices));
printf("ConstantBuffer updated\n");
EngineLog("After UpdateConstantBuffer");
StaticMeshComponent mesh;
printf("Starting mesh init...\n");
EngineLog("Before mesh.Initialize");
if (!mesh.Initialize(cmdList, "Res/Model/Sphere.lhsm")) {
printf("Load Mesh Failed!\n");
return -1;
}
printf("Mesh loaded\n");
EngineLog("After mesh.Initialize");
cmdList->Close();
printf("CommandList closed\n");
EngineLog("After cmdList->Close");
ICommandQueue* queue = device->GetCommandQueue();
void* cmdListPtr = cmdList->GetNativeCommandList();
queue->ExecuteCommandLists(&cmdListPtr, 1);
printf("Commands executed\n");
EngineLog("After ExecuteCommandLists");
ShowWindow(hwnd, nShowCmd);
UpdateWindow(hwnd);
MSG msg = {};
while (true) {
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT) break;
TranslateMessage(&msg);
DispatchMessage(&msg);
} else {
EngineLog("MainLoop: 1");
renderContext.BeginFrame();
EngineLog("MainLoop: 2");
renderContext.SetViewport((float)width, (float)height);
renderContext.SetScissor(width, height);
float color[4] = {0.5f, 0.5f, 0.5f, 1.0f};
renderContext.ClearRenderTarget(color);
renderContext.ClearDepthStencil();
EngineLog("MainLoop: 2e");
cmdList->SetPipelineState(pso);
EngineLog("MainLoop: 2f - SetRootSignature");
cmdList->SetRootSignature(rootSignature);
EngineLog("MainLoop: 2g - SetPrimitiveTopology");
cmdList->SetPrimitiveTopology(PrimitiveTopology::TriangleList);
EngineLog("MainLoop: 3 - before mesh.Render");
mesh.Render(cmdList);
EngineLog("MainLoop: 4");
renderContext.EndFrame();
EngineLog("MainLoop: 5");
renderContext.Present();
EngineLog("MainLoop: 6");
}
}
renderContext.Shutdown();
delete pso;
delete rootSignature;
delete cb;
delete device;
return 0;
}