|
@@ -48,6 +48,7 @@ static ID3D12Resource* g_mainRenderTargetResource[NUM_BACK_BUFFERS]
|
|
|
static D3D12_CPU_DESCRIPTOR_HANDLE g_mainRenderTargetDescriptor[NUM_BACK_BUFFERS] = {};
|
|
|
|
|
|
// Forward declarations of helper functions
|
|
|
+bool MainLoopStep();
|
|
|
bool CreateDeviceD3D(HWND hWnd);
|
|
|
void CleanupDeviceD3D();
|
|
|
void CreateRenderTarget();
|
|
@@ -111,121 +112,129 @@ int main(int, char**)
|
|
|
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
|
|
|
//IM_ASSERT(font != NULL);
|
|
|
|
|
|
- // Our state
|
|
|
- bool show_demo_window = true;
|
|
|
- bool show_another_window = false;
|
|
|
- ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
|
|
-
|
|
|
// Main loop
|
|
|
- bool done = false;
|
|
|
- while (!done)
|
|
|
+ while (true)
|
|
|
{
|
|
|
- // Poll and handle messages (inputs, window resize, etc.)
|
|
|
- // See the WndProc() function below for our to dispatch events to the Win32 backend.
|
|
|
- MSG msg;
|
|
|
- while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
|
|
|
- {
|
|
|
- ::TranslateMessage(&msg);
|
|
|
- ::DispatchMessage(&msg);
|
|
|
- if (msg.message == WM_QUIT)
|
|
|
- done = true;
|
|
|
- }
|
|
|
- if (done)
|
|
|
+ if (!MainLoopStep())
|
|
|
break;
|
|
|
+ }
|
|
|
|
|
|
- // Start the Dear ImGui frame
|
|
|
- ImGui_ImplDX12_NewFrame();
|
|
|
- ImGui_ImplWin32_NewFrame();
|
|
|
- ImGui::NewFrame();
|
|
|
+ // Cleanup
|
|
|
+ WaitForLastSubmittedFrame();
|
|
|
+ ImGui_ImplDX12_Shutdown();
|
|
|
+ ImGui_ImplWin32_Shutdown();
|
|
|
+ ImGui::DestroyContext();
|
|
|
|
|
|
- // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!).
|
|
|
- if (show_demo_window)
|
|
|
- ImGui::ShowDemoWindow(&show_demo_window);
|
|
|
+ CleanupDeviceD3D();
|
|
|
+ ::DestroyWindow(hwnd);
|
|
|
+ ::UnregisterClassW(wc.lpszClassName, wc.hInstance);
|
|
|
|
|
|
- // 2. Show a simple window that we create ourselves. We use a Begin/End pair to create a named window.
|
|
|
- {
|
|
|
- static float f = 0.0f;
|
|
|
- static int counter = 0;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
|
|
|
- ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it.
|
|
|
+bool MainLoopStep()
|
|
|
+{
|
|
|
+ // Poll and handle messages (inputs, window resize, etc.)
|
|
|
+ // See the WndProc() function below where we dispatch events to the imgui_impl_win32 backend.
|
|
|
+ bool done = false;
|
|
|
+ MSG msg;
|
|
|
+ while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
|
|
|
+ {
|
|
|
+ ::TranslateMessage(&msg);
|
|
|
+ ::DispatchMessage(&msg);
|
|
|
+ if (msg.message == WM_QUIT)
|
|
|
+ done = true;
|
|
|
+ }
|
|
|
+ if (done)
|
|
|
+ return false;
|
|
|
|
|
|
- ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too)
|
|
|
- ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state
|
|
|
- ImGui::Checkbox("Another Window", &show_another_window);
|
|
|
+ // Start the Dear ImGui frame
|
|
|
+ ImGui_ImplDX12_NewFrame();
|
|
|
+ ImGui_ImplWin32_NewFrame();
|
|
|
+ ImGui::NewFrame();
|
|
|
|
|
|
- ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
|
|
|
- ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
|
|
|
+ // Our state
|
|
|
+ // (we use static, which essentially makes the variable globals, as a convenience to keep the example code easy to follow)
|
|
|
+ static bool show_demo_window = true;
|
|
|
+ static bool show_another_window = false;
|
|
|
+ static ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
|
|
|
|
|
- if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated)
|
|
|
- counter++;
|
|
|
- ImGui::SameLine();
|
|
|
- ImGui::Text("counter = %d", counter);
|
|
|
+ // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!).
|
|
|
+ if (show_demo_window)
|
|
|
+ ImGui::ShowDemoWindow(&show_demo_window);
|
|
|
|
|
|
- ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
|
|
|
- ImGui::End();
|
|
|
- }
|
|
|
+ // 2. Show a simple window that we create ourselves. We use a Begin/End pair to create a named window.
|
|
|
+ {
|
|
|
+ static float f = 0.0f;
|
|
|
+ static int counter = 0;
|
|
|
|
|
|
- // 3. Show another simple window.
|
|
|
- if (show_another_window)
|
|
|
- {
|
|
|
- ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
|
|
|
- ImGui::Text("Hello from another window!");
|
|
|
- if (ImGui::Button("Close Me"))
|
|
|
- show_another_window = false;
|
|
|
- ImGui::End();
|
|
|
- }
|
|
|
+ ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it.
|
|
|
|
|
|
- // Rendering
|
|
|
- ImGui::Render();
|
|
|
-
|
|
|
- FrameContext* frameCtx = WaitForNextFrameResources();
|
|
|
- UINT backBufferIdx = g_pSwapChain->GetCurrentBackBufferIndex();
|
|
|
- frameCtx->CommandAllocator->Reset();
|
|
|
-
|
|
|
- D3D12_RESOURCE_BARRIER barrier = {};
|
|
|
- barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
|
|
- barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
|
|
- barrier.Transition.pResource = g_mainRenderTargetResource[backBufferIdx];
|
|
|
- barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
|
|
- barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
|
|
|
- barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
|
|
- g_pd3dCommandList->Reset(frameCtx->CommandAllocator, NULL);
|
|
|
- g_pd3dCommandList->ResourceBarrier(1, &barrier);
|
|
|
-
|
|
|
- // Render Dear ImGui graphics
|
|
|
- const float clear_color_with_alpha[4] = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w };
|
|
|
- g_pd3dCommandList->ClearRenderTargetView(g_mainRenderTargetDescriptor[backBufferIdx], clear_color_with_alpha, 0, NULL);
|
|
|
- g_pd3dCommandList->OMSetRenderTargets(1, &g_mainRenderTargetDescriptor[backBufferIdx], FALSE, NULL);
|
|
|
- g_pd3dCommandList->SetDescriptorHeaps(1, &g_pd3dSrvDescHeap);
|
|
|
- ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), g_pd3dCommandList);
|
|
|
- barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
|
|
- barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
|
|
|
- g_pd3dCommandList->ResourceBarrier(1, &barrier);
|
|
|
- g_pd3dCommandList->Close();
|
|
|
-
|
|
|
- g_pd3dCommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&g_pd3dCommandList);
|
|
|
-
|
|
|
- g_pSwapChain->Present(1, 0); // Present with vsync
|
|
|
- //g_pSwapChain->Present(0, 0); // Present without vsync
|
|
|
-
|
|
|
- UINT64 fenceValue = g_fenceLastSignaledValue + 1;
|
|
|
- g_pd3dCommandQueue->Signal(g_fence, fenceValue);
|
|
|
- g_fenceLastSignaledValue = fenceValue;
|
|
|
- frameCtx->FenceValue = fenceValue;
|
|
|
- }
|
|
|
+ ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too)
|
|
|
+ ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state
|
|
|
+ ImGui::Checkbox("Another Window", &show_another_window);
|
|
|
|
|
|
- WaitForLastSubmittedFrame();
|
|
|
+ ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
|
|
|
+ ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
|
|
|
|
|
|
- // Cleanup
|
|
|
- ImGui_ImplDX12_Shutdown();
|
|
|
- ImGui_ImplWin32_Shutdown();
|
|
|
- ImGui::DestroyContext();
|
|
|
+ if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated)
|
|
|
+ counter++;
|
|
|
+ ImGui::SameLine();
|
|
|
+ ImGui::Text("counter = %d", counter);
|
|
|
|
|
|
- CleanupDeviceD3D();
|
|
|
- ::DestroyWindow(hwnd);
|
|
|
- ::UnregisterClassW(wc.lpszClassName, wc.hInstance);
|
|
|
+ ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
|
|
|
+ ImGui::End();
|
|
|
+ }
|
|
|
|
|
|
- return 0;
|
|
|
+ // 3. Show another simple window.
|
|
|
+ if (show_another_window)
|
|
|
+ {
|
|
|
+ ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
|
|
|
+ ImGui::Text("Hello from another window!");
|
|
|
+ if (ImGui::Button("Close Me"))
|
|
|
+ show_another_window = false;
|
|
|
+ ImGui::End();
|
|
|
+ }
|
|
|
+
|
|
|
+ // Rendering
|
|
|
+ ImGui::Render();
|
|
|
+
|
|
|
+ FrameContext* frameCtx = WaitForNextFrameResources();
|
|
|
+ UINT backBufferIdx = g_pSwapChain->GetCurrentBackBufferIndex();
|
|
|
+ frameCtx->CommandAllocator->Reset();
|
|
|
+
|
|
|
+ D3D12_RESOURCE_BARRIER barrier = {};
|
|
|
+ barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
|
|
+ barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
|
|
+ barrier.Transition.pResource = g_mainRenderTargetResource[backBufferIdx];
|
|
|
+ barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
|
|
+ barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
|
|
|
+ barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
|
|
+ g_pd3dCommandList->Reset(frameCtx->CommandAllocator, NULL);
|
|
|
+ g_pd3dCommandList->ResourceBarrier(1, &barrier);
|
|
|
+
|
|
|
+ // Render Dear ImGui graphics
|
|
|
+ const float clear_color_with_alpha[4] = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w };
|
|
|
+ g_pd3dCommandList->ClearRenderTargetView(g_mainRenderTargetDescriptor[backBufferIdx], clear_color_with_alpha, 0, NULL);
|
|
|
+ g_pd3dCommandList->OMSetRenderTargets(1, &g_mainRenderTargetDescriptor[backBufferIdx], FALSE, NULL);
|
|
|
+ g_pd3dCommandList->SetDescriptorHeaps(1, &g_pd3dSrvDescHeap);
|
|
|
+ ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), g_pd3dCommandList);
|
|
|
+ barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
|
|
+ barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
|
|
|
+ g_pd3dCommandList->ResourceBarrier(1, &barrier);
|
|
|
+ g_pd3dCommandList->Close();
|
|
|
+
|
|
|
+ g_pd3dCommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&g_pd3dCommandList);
|
|
|
+
|
|
|
+ g_pSwapChain->Present(1, 0); // Present with vsync
|
|
|
+ //g_pSwapChain->Present(0, 0); // Present without vsync
|
|
|
+
|
|
|
+ UINT64 fenceValue = g_fenceLastSignaledValue + 1;
|
|
|
+ g_pd3dCommandQueue->Signal(g_fence, fenceValue);
|
|
|
+ g_fenceLastSignaledValue = fenceValue;
|
|
|
+ frameCtx->FenceValue = fenceValue;
|
|
|
+
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
// Helper functions
|