#include #include #include #include #include #include #include #include #include #include #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; }