aboutsummaryrefslogtreecommitdiff
path: root/samples/SampleBase/ui/CommonUIController.cpp
diff options
context:
space:
mode:
authorBryan Galdrikian <[email protected]>2017-02-24 09:32:20 -0800
committerBryan Galdrikian <[email protected]>2017-02-24 09:32:20 -0800
commite1bf674c16e3c8472b29574159c789cd3f0c64e0 (patch)
tree9f0cfce09c71a2c27ff19589fcad6cd83504477c /samples/SampleBase/ui/CommonUIController.cpp
parentfirst commit (diff)
downloadblast-e1bf674c16e3c8472b29574159c789cd3f0c64e0.tar.xz
blast-e1bf674c16e3c8472b29574159c789cd3f0c64e0.zip
Updating to [email protected] and [email protected] with a new directory structure.
NvBlast folder is gone, files have been moved to top level directory. README is changed to reflect this.
Diffstat (limited to 'samples/SampleBase/ui/CommonUIController.cpp')
-rw-r--r--samples/SampleBase/ui/CommonUIController.cpp621
1 files changed, 621 insertions, 0 deletions
diff --git a/samples/SampleBase/ui/CommonUIController.cpp b/samples/SampleBase/ui/CommonUIController.cpp
new file mode 100644
index 0000000..e56a124
--- /dev/null
+++ b/samples/SampleBase/ui/CommonUIController.cpp
@@ -0,0 +1,621 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, related documentation
+* and any modifications thereto. Any use, reproduction, disclosure or
+* distribution of this software and related documentation without an express
+* license agreement from NVIDIA CORPORATION is strictly prohibited.
+*/
+
+#include "CommonUIController.h"
+
+#include "Renderer.h"
+#include "BlastController.h"
+#include "DamageToolController.h"
+#include "SceneController.h"
+#include "SampleController.h"
+#include "PhysXController.h"
+#include "SampleProfiler.h"
+
+#include "PxVisualizationParameter.h"
+#include "PxScene.h"
+
+#include <imgui.h>
+#include "imgui_impl_dx11.h"
+#include "UIHelpers.h"
+
+#include <cstdio>
+#include <inttypes.h>
+
+
+inline float memorySizeOutput(const char*& prefix, float value)
+{
+ for (prefix = "\0\0k\0M\0G\0T\0P\0E"; value >= 1024 && *prefix != 'E'; value /= 1024, prefix += 2);
+ return value;
+}
+
+CommonUIController::CommonUIController()
+{
+}
+
+HRESULT CommonUIController::DeviceCreated(ID3D11Device* pDevice)
+{
+ DeviceManager* manager = GetDeviceManager();
+ ID3D11DeviceContext* pd3dDeviceContext;
+ pDevice->GetImmediateContext(&pd3dDeviceContext);
+ ImGui_ImplDX11_Init(manager->GetHWND(), pDevice, pd3dDeviceContext);
+
+ ImGuiStyle& style = ImGui::GetStyle();
+ style.WindowRounding = 8.0f;
+ style.ScrollbarRounding = 8.0f;
+ style.FrameRounding = 8.0f;
+ //style.IndentSpacing = 20;
+ int mainColor[3] = { 110, 110, 110 }; // previous green one { 50, 110, 30 }
+ style.Colors[ImGuiCol_TitleBg] = ImColor(mainColor[0], mainColor[1], mainColor[2], 62);
+ style.Colors[ImGuiCol_TitleBgCollapsed] = ImColor(mainColor[0], mainColor[1], mainColor[2], 52);
+ style.Colors[ImGuiCol_TitleBgActive] = ImColor(mainColor[0], mainColor[1], mainColor[2], 87);
+ style.Colors[ImGuiCol_Header] = ImColor(mainColor[0], mainColor[1], mainColor[2], 52);
+ style.Colors[ImGuiCol_HeaderHovered] = ImColor(mainColor[0], mainColor[1], mainColor[2], 92);
+ style.Colors[ImGuiCol_HeaderActive] = ImColor(mainColor[0], mainColor[1], mainColor[2], 72);
+ style.Colors[ImGuiCol_ScrollbarBg] = ImColor(mainColor[0], mainColor[1], mainColor[2], 12);
+ style.Colors[ImGuiCol_ScrollbarGrab] = ImColor(mainColor[0], mainColor[1], mainColor[2], 52);
+ style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImColor(mainColor[0], mainColor[1], mainColor[2], 92);
+ style.Colors[ImGuiCol_ScrollbarGrabActive] = ImColor(mainColor[0], mainColor[1], mainColor[2], 72);
+ style.Colors[ImGuiCol_Button] = ImColor(40, 100, 80, 30);
+ style.Colors[ImGuiCol_ButtonHovered] = ImColor(40, 100, 80, 100);
+ style.Colors[ImGuiCol_ButtonActive] = ImColor(40, 100, 80, 70);
+ style.Colors[ImGuiCol_PopupBg] = ImColor(10, 23, 18, 230);
+ style.Colors[ImGuiCol_TextSelectedBg] = ImColor(10, 23, 18, 180);
+ style.Colors[ImGuiCol_FrameBg] = ImColor(70, 70, 70, 30);
+ style.Colors[ImGuiCol_FrameBgHovered] = ImColor(70, 70, 70, 70);
+ style.Colors[ImGuiCol_FrameBgActive] = ImColor(70, 70, 70, 50);
+ style.Colors[ImGuiCol_ComboBg] = ImColor(20, 20, 20, 252);
+
+ return S_OK;
+}
+
+void CommonUIController::DeviceDestroyed()
+{
+ ImGui_ImplDX11_Shutdown();
+}
+
+extern LRESULT ImGui_ImplDX11_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+LRESULT CommonUIController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ PX_UNUSED(hWnd);
+ PX_UNUSED(wParam);
+ PX_UNUSED(lParam);
+
+ ImGui_ImplDX11_WndProcHandler(hWnd, uMsg, wParam, lParam);
+
+ if (uMsg == WM_KEYDOWN && !ImGui::GetIO().WantCaptureKeyboard)
+ {
+ int iKeyPressed = static_cast<int>(wParam);
+ switch (iKeyPressed)
+ {
+ case 'P':
+ {
+ getPhysXController().setPaused(!getPhysXController().isPaused());
+ break;
+ }
+ case 'O':
+ {
+ getRenderer().setWireframeMode(!getRenderer().getWireframeMode());
+ break;
+ }
+ case 'I':
+ {
+ getBlastController().debugRenderMode = (BlastFamily::DebugRenderMode)(((int)getBlastController().debugRenderMode + 1) % BlastFamily::DebugRenderMode::DEBUG_RENDER_MODES_COUNT);
+ break;
+ }
+ case VK_F5:
+ {
+ getRenderer().reloadShaders();
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (ImGui::GetIO().WantCaptureMouse)
+ return 0;
+
+ return 1;
+}
+
+void CommonUIController::Animate(double fElapsedTimeSeconds)
+{
+ m_dt = (float)fElapsedTimeSeconds;
+}
+
+void CommonUIController::Render(ID3D11Device*, ID3D11DeviceContext*, ID3D11RenderTargetView*, ID3D11DepthStencilView*)
+{
+ ImGui_ImplDX11_NewFrame();
+ drawUI();
+ ImGui::Render();
+}
+
+void CommonUIController::addDelayedCall(const char* title, const char* message, std::function<void()> func, float delay)
+{
+ DelayedCall call = { func, title, message, delay, delay };
+ m_delayedCalls.emplace(call);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// IMGUI UI
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+void CommonUIController::drawUI()
+{
+ const float padding = 8.0f;
+ ImGui::SetNextWindowPos(ImVec2(padding, padding), ImGuiSetCond_Once/*ImGuiSetCond_FirstUseEver*/);
+ ImGui::SetNextWindowSize(ImVec2(420, getRenderer().getScreenHeight() - 2 * padding), ImGuiSetCond_Once/*ImGuiSetCond_FirstUseEver*/);
+ ImGui::SetNextWindowCollapsed(false, ImGuiSetCond_Once);
+ ImGui::Begin("New Shiny UI", 0, ImGuiWindowFlags_NoTitleBar);
+ {
+ ImGui::PushItemWidth(ImGui::GetWindowSize().x * 0.5f);
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Scene
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ if (ImGui::CollapsingHeader("Scene"))
+ {
+ getSceneController().drawUI();
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Blast
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ if (ImGui::CollapsingHeader("Blast"))
+ {
+ getBlastController().drawUI();
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Damage Tool
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ if (ImGui::CollapsingHeader("Damage Tool"))
+ {
+ getDamageToolController().drawUI();
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Stats
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ if (ImGui::CollapsingHeader("Stats"))
+ {
+ BlastController& blastController = getBlastController();
+
+ const char* prefix;
+ float sizeVal;
+
+ // FPS
+ double averageTime = GetDeviceManager()->GetAverageFrameTime();
+ float fps = (averageTime > 0) ? 1.0 / averageTime : 0.0;
+ float frameMs = 1000.0f / fps;
+ ImGui::Text("Frame Time %.3f ms (%.1f FPS)", frameMs, fps);
+
+ static PlotLinesInstance<> fpsPlot;
+ fpsPlot.plot("FPS", frameMs, "ms/frame", 0.0f, 100.0f);
+
+ // Render stats
+ ImGui::PushStyleColor(ImGuiCol_Text, ImColor(0xFF, 0x3B, 0xD8, 0xFF));
+ ImGui::Text("Draw Calls (Opaque/Transparent): %d/%d", getRenderer().getVisibleOpaqueRenderablesCount(), getRenderer().getVisibleTransparentRenderablesCount());
+ ImGui::PopStyleColor();
+
+ // Blast stats
+ const BlastTimers& timers = blastController.getLastBlastTimers();
+
+ ImGui::Text("Simulation Time: %.2f ms ", getPhysXController().getLastSimulationTime() * 1000);
+ ImGui::Text("Actor Count: %d", blastController.getActorCount());
+ ImGui::Text("Visible Chunk Count: %d", blastController.getTotalVisibleChunkCount());
+
+ getManager()->getSceneController().drawStatsUI();
+
+ sizeVal = memorySizeOutput(prefix, (float)blastController.getFamilySize());
+ ImGui::Text("Family Size: %.3g %sB", sizeVal, prefix);
+ sizeVal = memorySizeOutput(prefix, (float)blastController.getBlastAssetsSize());
+ ImGui::Text("Blast asset Data size: %.3g %sB", sizeVal, prefix);
+
+ //ImGui::Text(" Last Blast Extern Time: %8.3f ms", timers.mLastExternalTime * 1000);
+// ImGui::Text(" Last Damage Time: %8.3f ms", timers.blastDamage * 1000);
+#if NV_PROFILE
+ ImGui::Text("Last Material Time: %8.3f ms", timers.blastDamageMaterial * 1000);
+ ImGui::Text("Last Fracture Time: %8.3f ms", timers.blastDamageFracture * 1000);
+#endif
+// ImGui::Text("Last Physics Split Time: %.3f ms", timers.physicsSplit * 1000);
+#if NV_PROFILE
+ ImGui::Text("Last Island Time: %8.3f ms", timers.blastSplitIsland * 1000);
+ ImGui::Text("Last Partition Time: %8.3f ms", timers.blastSplitPartition * 1000);
+ ImGui::Text("Last Visibility Time: %8.3f ms", timers.blastSplitVisibility * 1000);
+#endif
+
+#if NV_PROFILE
+ // Sample Profiler
+ static bool s_showProfilerWindow = false;
+ if (ImGui::Button("Code Profiler"))
+ {
+ s_showProfilerWindow = !s_showProfilerWindow;
+ }
+ if (s_showProfilerWindow)
+ {
+ drawCodeProfiler(&s_showProfilerWindow);
+ }
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Application
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ if (ImGui::CollapsingHeader("Application"))
+ {
+ // Paused
+ bool isPaused = getPhysXController().isPaused();
+ if (ImGui::Checkbox("Pause (P)", &isPaused))
+ {
+ getPhysXController().setPaused(isPaused);
+ }
+
+ // Reload Shaders
+ if (ImGui::Button("Reload Shaders (F5)"))
+ {
+ getRenderer().reloadShaders();
+ }
+
+ // ImGui Test Window (just in case)
+ static bool s_showTestWindow = false;
+ if (ImGui::Button("ImGui Test Window"))
+ {
+ s_showTestWindow = !s_showTestWindow;
+ }
+ if (s_showTestWindow)
+ {
+ ImGui::ShowTestWindow();
+ }
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Debug Render
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ if (ImGui::CollapsingHeader("Debug Render"))
+ {
+ // WireFrame
+ bool wireFrameEnabled = getRenderer().getWireframeMode();
+ if (ImGui::Checkbox("WireFrame (O)", &wireFrameEnabled))
+ {
+ getRenderer().setWireframeMode(wireFrameEnabled);
+ }
+
+ // - - - - - - - -
+ ImGui::Spacing();
+
+ // Blast Debug Render Mode
+ const char* debugRenderItems[] =
+ {
+ "Disabled", // DEBUG_RENDER_DISABLED
+ "Health Graph", // DEBUG_RENDER_HEALTH_GRAPH
+ "Centroids", // DEBUG_RENDER_CENTROIDS
+ "Health Graph + Centroids", // DEBUG_RENDER_HEALTH_GRAPH_CENTROIDS
+ "Joints", // DEBUG_RENDER_JOINTS
+ "Stress Graph", // DEBUG_RENDER_STRESS_GRAPH
+ "Stress Graph + Nodes Impulses", // DEBUG_RENDER_STRESS_GRAPH_NODES_IMPULSES
+ "Stress Graph + Bonds Impulses" // DEBUG_RENDER_STRESS_GRAPH_BONDS_IMPULSES
+ };
+ ImGui::Combo("Blast Debug Render Mode (I)", (int*)&getBlastController().debugRenderMode, debugRenderItems, IM_ARRAYSIZE(debugRenderItems), -1);
+
+ // Blast Debug Render Scale
+ ImGui::DragFloat("Blast Debug Render Scale", &getBlastController().debugRenderScale, 0.01f, 0.0f, 10.0f, "%.3f", 4.0f);
+
+ // - - - - - - - -
+ ImGui::Spacing();
+
+ // PhysX Debug Render
+ if (ImGui::TreeNode("PhysX Debug Render"))
+ {
+ auto addParam = [&](physx::PxVisualizationParameter::Enum param, const char* uiName)
+ {
+ bool enabled = getPhysXController().getPhysXScene().getVisualizationParameter(param) != 0;
+ if (ImGui::Checkbox(uiName, &enabled))
+ {
+ getPhysXController().getPhysXScene().setVisualizationParameter(param, enabled ? 1.0f : 0.0f);
+ }
+ };
+
+ addParam(PxVisualizationParameter::eSCALE, "Scale");
+ addParam(PxVisualizationParameter::eBODY_AXES, "Body Axes");
+ addParam(PxVisualizationParameter::eWORLD_AXES, "World Axes");
+ addParam(PxVisualizationParameter::eBODY_MASS_AXES, "Body Mass Axes");
+ addParam(PxVisualizationParameter::eBODY_LIN_VELOCITY, "Body Lin Velocity");
+ addParam(PxVisualizationParameter::eBODY_ANG_VELOCITY, "Body Ang Velocity");
+ addParam(PxVisualizationParameter::eBODY_JOINT_GROUPS, "Body Joint");
+ addParam(PxVisualizationParameter::eCONTACT_POINT, "Contact Point");
+ addParam(PxVisualizationParameter::eCONTACT_NORMAL, "Contact Normal");
+ addParam(PxVisualizationParameter::eCONTACT_ERROR, "Contact Error");
+ addParam(PxVisualizationParameter::eCONTACT_FORCE, "Contact Force");
+ addParam(PxVisualizationParameter::eACTOR_AXES, "Actor Axes");
+ addParam(PxVisualizationParameter::eCOLLISION_AABBS, "Collision AABBs");
+ addParam(PxVisualizationParameter::eCOLLISION_SHAPES, "Collision Shapes");
+ addParam(PxVisualizationParameter::eCOLLISION_AXES, "Collision Axes");
+ addParam(PxVisualizationParameter::eCOLLISION_COMPOUNDS, "Collision Compounds");
+ addParam(PxVisualizationParameter::eCOLLISION_FNORMALS, "Collision FNormals");
+ addParam(PxVisualizationParameter::eCOLLISION_EDGES, "Collision Edges");
+ addParam(PxVisualizationParameter::eCOLLISION_STATIC, "Collision Static");
+ addParam(PxVisualizationParameter::eCOLLISION_DYNAMIC, "Collision Dynamic");
+ //addParam(PxVisualizationParameter::eDEPRECATED_COLLISION_PAIRS, "Collision Pairs");
+ addParam(PxVisualizationParameter::eJOINT_LOCAL_FRAMES, "Joint Local Frames");
+ addParam(PxVisualizationParameter::eJOINT_LIMITS, "Joint Limits");
+ //addParam(PxVisualizationParameter::ePARTICLE_SYSTEM_POSITION, "PS Position");
+ //addParam(PxVisualizationParameter::ePARTICLE_SYSTEM_VELOCITY, "PS Velocity");
+ //addParam(PxVisualizationParameter::ePARTICLE_SYSTEM_COLLISION_NORMAL, "PS Collision Normal");
+ //addParam(PxVisualizationParameter::ePARTICLE_SYSTEM_BOUNDS, "PS Bounds");
+ //addParam(PxVisualizationParameter::ePARTICLE_SYSTEM_GRID, "PS Grid");
+ //addParam(PxVisualizationParameter::ePARTICLE_SYSTEM_BROADPHASE_BOUNDS, "PS Broadphase Bounds");
+ //addParam(PxVisualizationParameter::ePARTICLE_SYSTEM_MAX_MOTION_DISTANCE, "PS Max Motion Distance");
+ addParam(PxVisualizationParameter::eCULL_BOX, "Cull Box");
+ //addParam(PxVisualizationParameter::eCLOTH_VERTICAL, "Cloth Vertical");
+ //addParam(PxVisualizationParameter::eCLOTH_HORIZONTAL, "Cloth Horizontal");
+ //addParam(PxVisualizationParameter::eCLOTH_BENDING, "Cloth Bending");
+ //addParam(PxVisualizationParameter::eCLOTH_SHEARING, "Cloth Shearing");
+ //addParam(PxVisualizationParameter::eCLOTH_VIRTUAL_PARTICLES, "Cloth Virtual Particles");
+ addParam(PxVisualizationParameter::eMBP_REGIONS, "MBP Regions");
+
+ ImGui::TreePop();
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // PhysX
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ if (ImGui::CollapsingHeader("PhysX"))
+ {
+ // PhysX
+ getPhysXController().drawUI();
+
+ // GPU
+ getSampleController().drawPhysXGpuUI();
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Renderer
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ if (ImGui::CollapsingHeader("Renderer"))
+ {
+ getRenderer().drawUI();
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Hints
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ if (ImGui::CollapsingHeader("Hints / Help"))
+ {
+ ImGui::BulletText("Rotate camera - RMB");
+ ImGui::BulletText("Move camera - WASDQE(SHIFT)");
+ ImGui::BulletText("Play/Pause - P");
+ ImGui::BulletText("Reload shaders - F5");
+ ImGui::BulletText("Wireframe - O");
+ ImGui::BulletText("Blast Debug Render - I");
+ ImGui::BulletText("Apply damage - LMB");
+ ImGui::BulletText("Damage radius - +/-/wheel");
+ ImGui::BulletText("Damage profile - 1-9");
+ ImGui::BulletText("Explosive - X");
+ ImGui::BulletText("Throw cube - F");
+ ImGui::BulletText("Restart - R");
+ }
+
+ ImGui::PopItemWidth();
+ }
+ ImGui::End();
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Mode Text
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ {
+ ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4());
+ ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0,0));
+
+ const char* text = getDamageToolController().isDamageMode() ? "DAMAGE MODE (PRESS SPACE)" : "DRAG MODE (PRESS SPACE)";
+ ImVec2 size = ImGui::CalcTextSize(text);
+ ImGui::SetNextWindowPos(ImVec2((getRenderer().getScreenWidth() - size.x) / 2, 0));
+ ImGui::Begin("Mode Text", 0, ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar);
+ ImGui::Text(text);
+ ImGui::End();
+
+ ImGui::PopStyleVar();
+ ImGui::PopStyleColor();
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // FPS
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ {
+ ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4());
+ ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
+
+ double averageTime = GetDeviceManager()->GetAverageFrameTime();
+ float fps = (averageTime > 0) ? 1.0 / averageTime : 0.0;
+ static char buf[32];
+ std::sprintf(buf, "%.1f FPS", fps);
+ ImVec2 size = ImGui::CalcTextSize(buf);
+
+ size.x += 20.0;
+ ImGui::SetNextWindowSize(size);
+ ImGui::SetNextWindowPos(ImVec2(getRenderer().getScreenWidth() - size.x, 0));
+ ImGui::Begin("FPS", 0, ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar);
+ ImGui::Text(buf);
+ ImGui::End();
+
+ ImGui::PopStyleVar();
+ ImGui::PopStyleColor();
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Loading overlay
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ if (!m_delayedCalls.empty())
+ {
+ DelayedCall& call = m_delayedCalls.front();
+ if (call.delay > 0)
+ {
+ const int height = 50;
+ const char* message = call.message;
+ const float alpha = PxClamp(lerp(0.0f, 1.0f, (call.delayTotal - call.delay) * 10.0f), 0.0f, 1.0f);
+
+ ImGui::PushStyleColor(ImGuiCol_WindowBg, ImColor(0, 0, 0, 200));
+ ImGui::PushStyleVar(ImGuiStyleVar_Alpha, alpha);
+ ImGui::SetNextWindowPosCenter();
+ ImVec2 size = ImGui::CalcTextSize(message);
+ int width = std::max<float>(200, size.x) + 50;
+ ImGui::SetNextWindowSize(ImVec2(width, height));
+ ImGui::Begin(call.title, 0, ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar);
+ ImGui::SetCursorPos(ImVec2((width - size.x) * 0.5f, (height - size.y) * 0.5f));
+ ImGui::Text(message);
+ ImGui::End();
+ ImGui::PopStyleVar();
+ ImGui::PopStyleColor();
+
+ call.delay -= PxClamp(m_dt, 0.0f, 0.1f);
+ }
+ else
+ {
+ call.func();
+ m_delayedCalls.pop();
+ }
+ }
+}
+
+
+void CommonUIController::drawCodeProfiler(bool* open)
+{
+ ImGuiWindowFlags window_flags = 0;
+ const float padding = 8.0f;
+ const float width = 550;
+ const float height = 580;
+ ImGui::SetNextWindowPos(ImVec2(getRenderer().getScreenWidth() - width - padding, padding), ImGuiSetCond_Once/*ImGuiSetCond_FirstUseEver*/);
+ ImGui::SetNextWindowSize(ImVec2(width, height), ImGuiSetCond_Once);
+ if (!ImGui::Begin("Code Profiler", open, window_flags))
+ {
+ // Early out if the window is collapsed, as an optimization.
+ ImGui::End();
+ return;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Control/Main Bar
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ {
+ if (ImGui::Button("Reset"))
+ {
+ PROFILER_INIT();
+ }
+ ImGui::SameLine();
+ if (ImGui::Button("Dump To File (profile.txt)"))
+ {
+ SampleProfilerDumpToFile("profile.txt");
+ }
+ ImGui::SameLine();
+ ImGui::Text("Profiler overhead: %2.3f ms", SampleProfilerGetOverhead().count() * 0.001f);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Legend
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ {
+ ImGui::Spacing(); ImGui::Separator(); ImGui::Spacing();
+ ImGui::Text("Legend: name | calls | time | max time");
+ ImGui::Spacing(); ImGui::Separator(); ImGui::Spacing();
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Stats Tree
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ ImGui::SetNextTreeNodeOpen(true, ImGuiSetCond_Once);
+ float plotMS = 0.0f;
+ float plotMaxMS = 0.0f;
+ const char* plotName = nullptr;
+ if (ImGui::TreeNode("Root"))
+ {
+ auto treeIt = SampleProfilerCreateTreeIterator();
+ if (treeIt)
+ {
+ uint32_t depth = 1;
+ uint32_t openeDepth = 1;
+ while (!treeIt->isDone())
+ {
+ const auto data = treeIt->data();
+
+ while (data->depth < depth)
+ {
+ ImGui::TreePop();
+ depth--;
+ }
+
+ const uint32_t maxLen = 30;
+ auto hash = data->hash;
+ static uint64_t selectedNodeHash = 0;
+ if (selectedNodeHash == hash)
+ {
+ plotMS = data->time.count() * 0.001f;
+ plotMaxMS = data->maxTime.count() * 0.001f;
+ plotName = data->name;
+ }
+ if (ImGui::TreeNodeEx(data->name, data->hasChilds ? 0 : ImGuiTreeNodeFlags_Leaf, "%-*.*s | %d | %2.3f ms | %2.3f ms",
+ maxLen, maxLen, data->name, data->calls, data->time.count() * 0.001f, data->maxTime.count() * 0.001f))
+ {
+ depth++;
+ treeIt->next();
+ }
+ else
+ {
+ treeIt->next();
+ while (!treeIt->isDone() && treeIt->data()->depth > depth)
+ treeIt->next();
+ }
+
+ if (ImGui::IsItemClicked())
+ {
+ selectedNodeHash = hash;
+ }
+ }
+
+ while (depth > 0)
+ {
+ ImGui::TreePop();
+ depth--;
+ }
+
+ treeIt->release();
+ }
+ else
+ {
+ ImGui::Text("Profiler Is Broken. Begin/End Mismatch.");
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Selected Item Plot
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ {
+ ImGui::Spacing(); ImGui::Separator(); ImGui::Spacing();
+ if (plotName)
+ {
+ static PlotLinesInstance<> selectedNodePlot;
+ selectedNodePlot.plot("", plotMS, plotName, 0.0f, plotMaxMS);
+ }
+ else
+ {
+ ImGui::Text("Select item to plot.");
+ }
+ }
+
+ ImGui::End();
+} \ No newline at end of file