Skip to content

Commit dbbefb9

Browse files
committed
Rework 3D bounding box visualisations and remove implot3d
The new DebugDraw can draw boxes over the 3D view, which is way easier then having them shown in a graph. I migrated all the implot3d visualization features to a proper DebugDraw version, like name drawing and showing dots for all actors.
1 parent 94ce86e commit dbbefb9

File tree

12 files changed

+82
-205
lines changed

12 files changed

+82
-205
lines changed

CMakeLists.txt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ find_package(OpenXR CONFIG REQUIRED)
3737
find_package(glm CONFIG REQUIRED)
3838
find_package(imgui CONFIG REQUIRED)
3939
find_package(implot CONFIG REQUIRED)
40-
find_package(implot3d CONFIG REQUIRED)
4140

4241
# Add DLL target
4342
add_library(BetterVR_Layer SHARED)
@@ -122,7 +121,6 @@ target_include_directories(BetterVR_Layer SYSTEM PRIVATE ${VULKAN_HEADERS_INCLUD
122121
target_link_libraries(BetterVR_Layer PRIVATE glm::glm)
123122
target_link_libraries(BetterVR_Layer PRIVATE imgui::imgui)
124123
target_link_libraries(BetterVR_Layer PRIVATE implot::implot)
125-
target_link_libraries(BetterVR_Layer PRIVATE implot3d::implot3d)
126124

127125

128126
# Add manual dependencies for DLL
@@ -136,4 +134,4 @@ install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/resources/BetterVR_Layer.json" DESTIN
136134
#install(CODE "file(REMOVE_RECURSE \"${CMAKE_INSTALL_PREFIX}/graphicPacks/BreathOfTheWild_BetterVR\")")
137135
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/resources/BreathOfTheWild_BetterVR" DESTINATION "${CMAKE_INSTALL_PREFIX}/graphicPacks")
138136
install(TARGETS BetterVR_Layer DESTINATION "${CMAKE_INSTALL_PREFIX}")
139-
install(FILES $<TARGET_PDB_FILE:BetterVR_Layer> DESTINATION "${CMAKE_INSTALL_PREFIX}" OPTIONAL)
137+
install(FILES $<TARGET_PDB_FILE:BetterVR_Layer> DESTINATION "${CMAKE_INSTALL_PREFIX}" OPTIONAL)

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,5 +156,4 @@ This project is licensed under the MIT license.
156156
BetterVR also uses the following libraries:
157157
- [vkroots (MIT licensed)](https://github.com/Joshua-Ashton/vkroots/blob/main/LICENSES/MIT.txt)
158158
- [imgui (MIT licensed)](https://github.com/ocornut/imgui/blob/master/LICENSE.txt)
159-
- [ImPlot3D (MIT licensed)](https://github.com/brenocq/implot3d/blob/main/LICENSE)
160159
- [ImPlot (MIT licensed)](https://github.com/epezent/implot/blob/master/LICENSE)

include/pch.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ using Microsoft::WRL::ComPtr;
5353
#define IMGUI_DEFINE_MATH_OPERATORS
5454
#include <imgui.h>
5555
#include <imgui_impl_vulkan.h>
56-
#include <implot3d.h>
5756
#include <implot.h>
5857

5958
// glm includes

src/hooking/camera.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,10 @@ void CemuHooks::hook_VisualizeRayCastHits(PPCInterpreter_t* hCPU) {
10851085
return;
10861086
}
10871087

1088+
if (!VRManager::instance().Hooks->m_entityDebugger || !VRManager::instance().Hooks->m_entityDebugger->ShouldDrawRaycastLines()) {
1089+
return;
1090+
}
1091+
10881092
uint32_t rayCastResultPtr = hCPU->gpr[3];
10891093
glm::fvec3 raycastHitPos = getMemory<BEVec3>(hCPU->gpr[4]).getLE();
10901094

src/hooking/entity_controller.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
bool shouldAdjustArrowTarget = false;
44

5+
// CarryBox is used to carry all the veggies in the game while cooking
6+
// GameSceneSubsys12::x(GameSceneSubsys12::sInstance) returns 0 for carryable, 1 is for carryable
7+
8+
59
void CemuHooks::hook_LoadDynamicBool(PPCInterpreter_t* hCPU) {
610
hCPU->instructionPointer = hCPU->sprNew.LR;
711
hCPU->sprNew.LR = hCPU->gpr[0];

src/hooking/entity_debugger.cpp

Lines changed: 38 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
#include <imgui_memory_editor.h>
77

8-
#include "implot3d_internal.h"
98
#include "utils/debug_draw.h"
109

1110
std::mutex g_actorListMutex;
@@ -89,9 +88,6 @@ void EntityDebugger::UpdateEntityMemory() {
8988
if (actorData.first == "GameROMPlayer") {
9089
CemuHooks::readMemory(actorData.second + offsetof(ActorWiiU, mtx), &playerPos);
9190
glm::fvec3 newPlayerPos = playerPos.getPos().getLE();
92-
if (glm::distance(newPlayerPos, m_playerPos) > 25.0f) {
93-
m_resetPlot = true;
94-
}
9591
m_playerPos = newPlayerPos;
9692

9793
// // set invisibility flag
@@ -194,19 +190,39 @@ void EntityDebugger::UpdateEntityMemory() {
194190
SetAABB(actorId, aabbMin.getLE(), aabbMax.getLE());
195191
}
196192

197-
if (float distance = glm::distance(m_playerPos, mtx.getPos().getLE()); distance <= 100.0f) {
198-
glm::fvec3 pos = mtx.getPos().getLE();
199-
glm::fquat rot = mtx.getRotLE();
193+
float distance = glm::distance(m_playerPos, mtx.getPos().getLE());
194+
glm::fvec3 pos = mtx.getPos().getLE();
195+
glm::fquat rot = mtx.getRotLE();
200196

201-
glm::fvec3 localMin = aabbMin.getLE();
202-
glm::fvec3 localMax = aabbMax.getLE();
203-
glm::fvec3 localCenter = (localMin + localMax) * 0.5f;
204-
glm::fvec3 halfExtents = (localMax - localMin) * 0.5f;
197+
glm::fvec3 localMin = aabbMin.getLE();
198+
glm::fvec3 localMax = aabbMax.getLE();
199+
glm::fvec3 localCenter = (localMin + localMax) * 0.5f;
200+
glm::fvec3 halfExtents = (localMax - localMin) * 0.5f;
201+
bool matchesFilter = m_filter.empty() || actorName.find(m_filter) != std::string::npos;
205202

206-
// Transform local AABB center to world space
207-
glm::fvec3 worldCenter = pos + glm::mat3_cast(rot) * localCenter;
203+
if (m_showWorldLabels && matchesFilter && distance <= 100.0f) {
204+
float labelFontScale = 0.325f;
205+
if (distance <= 8.0f) {
206+
labelFontScale = 0.72f;
207+
}
208+
else if (distance <= 16.0f) {
209+
labelFontScale = 0.6f;
210+
}
211+
else if (distance <= 40.0f) {
212+
labelFontScale = 0.45f;
213+
}
208214

209-
DebugDraw::instance().Box(worldCenter, halfExtents, rot, IM_COL32(255, 255, 255, 255/10), 1.0f);
215+
DebugDraw::instance().Text(pos, actorName, IM_COL32(255, 255, 255, 255), ImVec2(6.0f, -18.0f), labelFontScale);
216+
}
217+
218+
if (m_showWorldAABBs && matchesFilter && distance <= m_worldAABBMaxDistance) {
219+
if (glm::all(glm::greaterThan(halfExtents, glm::vec3(0.0f)))) {
220+
glm::fvec3 worldCenter = pos + glm::mat3_cast(rot) * localCenter;
221+
DebugDraw::instance().Box(worldCenter, halfExtents, rot, IM_COL32(255, 255, 255, 255 / 10), 1.0f);
222+
}
223+
else {
224+
DebugDraw::instance().Dot(pos, 3.0f, IM_COL32(255, 255, 255, 180));
225+
}
210226
}
211227

212228
// uint32_t physicsMtxPtr = 0;
@@ -275,41 +291,6 @@ void EntityDebugger::UpdateEntityMemory() {
275291
}
276292
}
277293
}
278-
279-
280-
void DrawAABBInPlot(glm::fvec3 pos, glm::fvec3& min, glm::fvec3& max, glm::fquat& rotation) {
281-
glm::fvec3 corners[8] = {
282-
{min.x, min.y, min.z},
283-
{max.x, min.y, min.z},
284-
{max.x, max.y, min.z},
285-
{min.x, max.y, min.z},
286-
{min.x, min.y, max.z},
287-
{max.x, min.y, max.z},
288-
{max.x, max.y, max.z},
289-
{min.x, max.y, max.z}
290-
};
291-
292-
glm::mat4 transform = glm::translate(glm::mat4(1.0f), pos) * glm::mat4_cast(rotation);
293-
294-
ImPlot3DPoint aabbPoints[8];
295-
for (int i = 0; i < 8; ++i) {
296-
glm::vec4 worldPos = transform * glm::vec4(corners[i], 1.0f);
297-
aabbPoints[i] = ImPlot3DPoint(worldPos.x, worldPos.z, worldPos.y);
298-
}
299-
300-
int edges[12][2] = {
301-
{0, 1}, {1, 2}, {2, 3}, {3, 0}, // near plane
302-
{4, 5}, {5, 6}, {6, 7}, {7, 4}, // far plane
303-
{0, 4}, {1, 5}, {2, 6}, {3, 7} // connecting edges
304-
};
305-
306-
for (const auto& edge : edges) {
307-
ImVec2 p0 = ImPlot3D::PlotToPixels(aabbPoints[edge[0]]);
308-
ImVec2 p1 = ImPlot3D::PlotToPixels(aabbPoints[edge[1]]);
309-
ImPlot3D::GetPlotDrawList()->AddLine(p0, p1, IM_COL32(255, 0, 0, 255));
310-
}
311-
}
312-
313294
void EntityDebugger::DrawEntityInspector() {
314295
ImGui::Begin("BetterVR Debugger");
315296

@@ -319,54 +300,14 @@ void EntityDebugger::DrawEntityInspector() {
319300

320301
ImGui::BeginChild("ScrollArea", ImVec2(0, 0));
321302

322-
if (ImGui::CollapsingHeader("World Space Inspector")) {
323-
ImGui::Checkbox("Disable Points For Entities", &m_disablePoints);
324-
ImGui::Checkbox("Disable Text For Entities", &m_disableTexts);
325-
ImGui::Checkbox("Disable Rotations For Entities", &m_disableRotations);
326-
ImGui::Checkbox("Disable AABBs For Entities", &m_disableAABBs);
327-
328-
if (ImPlot3D::BeginPlot("##plot", ImVec2(-1, 0), ImPlot3DFlags_NoLegend | ImPlot3DFlags_NoTitle)) {
329-
// add -50 and 50 to playerPos to make the plot centered around the player
330-
constexpr float zoomOutAxis = 30.0f;
331-
ImPlot3D::SetupAxesLimits(
332-
-zoomOutAxis, +zoomOutAxis,
333-
-zoomOutAxis, +zoomOutAxis,
334-
-zoomOutAxis, +zoomOutAxis,
335-
ImPlot3DCond_Once
336-
);
337-
ImPlot3D::SetupAxes("X", "Z", "Y");
338-
339-
if (m_resetPlot) {
340-
ImPlot3D::GetCurrentPlot()->Axes[ImAxis3D_X].SetRange(m_playerPos.x-zoomOutAxis, m_playerPos.x+zoomOutAxis);
341-
ImPlot3D::GetCurrentPlot()->Axes[ImAxis3D_Y].SetRange(m_playerPos.z-zoomOutAxis, m_playerPos.z+zoomOutAxis);
342-
ImPlot3D::GetCurrentPlot()->Axes[ImAxis3D_Z].SetRange(m_playerPos.y-zoomOutAxis, m_playerPos.y+zoomOutAxis);
343-
m_resetPlot = false;
344-
}
345-
346-
// plot entities in 3D space
347-
for (auto& entity : m_entities | std::views::values) {
348-
if (!m_disableTexts) {
349-
ImPlot3D::PlotText(entity.name.c_str(), entity.position.x.getLE(), entity.position.z.getLE(), entity.position.y.getLE(), 0, ImVec2(0, 5));
350-
}
351-
if (!m_disablePoints) {
352-
ImVec2 cntr = ImPlot3D::PlotToPixels(ImPlot3DPoint(entity.position.x.getLE(), entity.position.z.getLE(), entity.position.y.getLE()));
353-
ImPlot3D::GetPlotDrawList()->AddCircleFilled(cntr, 2, IM_COL32(255, 255, 0, 255), 8);
354-
}
355-
if (!m_disableRotations) {
356-
glm::fvec3 start = entity.position.getLE();
357-
glm::fvec3 end = entity.rotation * entity.position.getLE() * 0.05f;
358-
float xList[] = { start.x, end.x };
359-
float yList[] = { start.z, end.z };
360-
float zList[] = { start.y, end.y };
361-
ImPlot3D::PlotLine(entity.name.c_str(), xList, yList, zList, 2);
362-
}
363-
if (!m_disableAABBs) {
364-
DrawAABBInPlot(entity.position.getLE(), entity.aabbMin, entity.aabbMax, entity.rotation);
365-
}
366-
}
367-
368-
ImPlot3D::EndPlot();
303+
if (ImGui::CollapsingHeader("World Space Overlay", ImGuiTreeNodeFlags_DefaultOpen)) {
304+
ImGui::Checkbox("Show Entity Names In 3D View", &m_showWorldLabels);
305+
ImGui::Checkbox("Show Entity Boxes In 3D View", &m_showWorldAABBs);
306+
if (m_showWorldAABBs) {
307+
ImGui::SetNextItemWidth(160.0f);
308+
ImGui::DragFloat("3D Box Distance", &m_worldAABBMaxDistance, 1.0f, 0.0f, 10000.0f, "%.0f");
369309
}
310+
ImGui::Checkbox("Show Raycast Lines", &m_showRaycastLines);
370311
}
371312

372313
// display entities
@@ -774,4 +715,4 @@ void EntityDebugger::DrawFPSOverlayContent(RND_Renderer* renderer, bool renderTe
774715

775716
ImPlot::EndPlot();
776717
}
777-
}
718+
}

src/hooking/entity_debugger.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class EntityDebugger {
2323

2424
void UpdateKeyboardControls();
2525
void DrawEntityInspector();
26+
bool ShouldDrawRaycastLines() const { return m_showRaycastLines; }
2627
static void DrawFPSOverlay(class RND_Renderer* renderer);
2728
static void DrawFPSOverlayContent(class RND_Renderer* renderer, bool renderText);
2829

@@ -47,12 +48,11 @@ class EntityDebugger {
4748

4849
std::unordered_map<uint32_t, Entity> m_entities;
4950
glm::fvec3 m_playerPos = {};
50-
bool m_resetPlot = false;
5151

5252
private:
5353
std::string m_filter = std::string(256, '\0');
54-
bool m_disablePoints = true;
55-
bool m_disableTexts = false;
56-
bool m_disableRotations = true;
57-
bool m_disableAABBs = false;
58-
};
54+
bool m_showWorldLabels = false;
55+
bool m_showWorldAABBs = false;
56+
float m_worldAABBMaxDistance = 100.0f;
57+
bool m_showRaycastLines = false;
58+
};

src/hooking/weapon.h

Lines changed: 1 addition & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -424,79 +424,6 @@ class WeaponMotionAnalyser {
424424

425425
const auto oldestIdx = [this](uint32_t j) { return (m_lastSampleIdx + j) % MAX_SAMPLES; };
426426

427-
auto drawSnapshot = [](const char* title, const glm::vec3& currDir, glm::vec3& lastDir, bool& lastValid, float threshold, const ImVec4& colLast, const ImVec4& colCurr) {
428-
const float mag = glm::length(currDir);
429-
glm::vec3 unit = mag > 0.f ? currDir / mag : glm::vec3{ 0 };
430-
if (mag >= threshold) {
431-
lastDir = unit;
432-
lastValid = true;
433-
}
434-
435-
const float lastS[6] = { 0, 0, 0, lastDir.x, lastDir.z, lastDir.y };
436-
const float currS[6] = { 0, 0, 0, unit.x, unit.z, unit.y };
437-
438-
if (ImPlot3D::BeginPlot(title, { 0, 230 }, ImPlot3DFlags_NoTitle)) {
439-
ImPlot3D::SetupAxes("X", "Z", "Y", ImPlot3DAxisFlags_LockMin | ImPlot3DAxisFlags_LockMax, ImPlot3DAxisFlags_LockMin | ImPlot3DAxisFlags_LockMax, ImPlot3DAxisFlags_LockMin | ImPlot3DAxisFlags_LockMax);
440-
ImPlot3D::SetupAxisLimits(ImAxis3D_X, -1.1f, 1.1f, ImPlot3DCond_Always);
441-
ImPlot3D::SetupAxisLimits(ImAxis3D_Y, -1.1f, 1.1f, ImPlot3DCond_Always);
442-
ImPlot3D::SetupAxisLimits(ImAxis3D_Z, -1.1f, 1.1f, ImPlot3DCond_Always);
443-
444-
if (lastValid) {
445-
ImPlot3D::SetNextLineStyle(colLast, 3);
446-
ImPlot3D::PlotLine("Last", lastS, lastS + 1, lastS + 2, 2, ImPlot3DLineFlags_Segments, 0, sizeof(float) * 3);
447-
}
448-
if (mag > 0) {
449-
ImPlot3D::SetNextLineStyle(colCurr, 2);
450-
ImPlot3D::PlotLine("Curr", currS, currS + 1, currS + 2, 2, ImPlot3DLineFlags_Segments, 0, sizeof(float) * 3);
451-
}
452-
ImPlot3D::EndPlot();
453-
}
454-
ImGui::SameLine();
455-
};
456-
457-
std::array<float, MAX_SAMPLES> posX{}, posY{}, posZ{};
458-
std::array<float, MAX_SAMPLES * 2> velLineX{}, velLineY{}, velLineZ{};
459-
float xMin = FLT_MAX, xMax = -FLT_MAX, yMin = FLT_MAX, yMax = -FLT_MAX, zMin = FLT_MAX, zMax = -FLT_MAX;
460-
461-
for (uint32_t j = 0; j < MAX_SAMPLES; ++j) {
462-
const auto& s = m_rollingSamples[oldestIdx(j)];
463-
464-
posX[j] = s.position.x;
465-
posY[j] = s.position.z; // swap Y/Z for nicer view
466-
posZ[j] = s.position.y;
467-
468-
xMin = std::min(xMin, posX[j]);
469-
xMax = std::max(xMax, posX[j]);
470-
yMin = std::min(yMin, posY[j]);
471-
yMax = std::max(yMax, posY[j]);
472-
zMin = std::min(zMin, posZ[j]);
473-
zMax = std::max(zMax, posZ[j]);
474-
475-
const auto av = s.rotatedAngularVelocity() * 0.05f;
476-
477-
velLineX[j * 2] = posX[j];
478-
velLineX[j * 2 + 1] = posX[j] + av.x;
479-
velLineY[j * 2] = posY[j];
480-
velLineY[j * 2 + 1] = posY[j] + av.y;
481-
velLineZ[j * 2] = posZ[j];
482-
velLineZ[j * 2 + 1] = posZ[j] + av.z;
483-
}
484-
485-
if (ImPlot3D::BeginPlot("Weapon Motion", { 0, 300 }, ImPlot3DFlags_NoTitle)) {
486-
ImPlot3D::SetupAxes("X", "Z", "Y", ImPlot3DAxisFlags_LockMin | ImPlot3DAxisFlags_LockMax, ImPlot3DAxisFlags_LockMin | ImPlot3DAxisFlags_LockMax, ImPlot3DAxisFlags_LockMin | ImPlot3DAxisFlags_LockMax);
487-
ImPlot3D::SetupAxisLimits(ImAxis3D_X, xMin - 0.1f, xMax + 0.1f, ImPlot3DCond_Always);
488-
ImPlot3D::SetupAxisLimits(ImAxis3D_Y, yMin - 0.1f, yMax + 0.1f, ImPlot3DCond_Always);
489-
ImPlot3D::SetupAxisLimits(ImAxis3D_Z, zMin - 0.1f, zMax + 0.1f, ImPlot3DCond_Always);
490-
491-
ImPlot3D::SetNextMarkerStyle(ImPlot3DMarker_Circle, 1.5f);
492-
ImPlot3D::PlotScatter("Pos", posX.data(), posY.data(), posZ.data(), MAX_SAMPLES);
493-
494-
ImPlot3D::SetNextLineStyle(ImVec4(0, 1, 0.5f, 0.5f), 1.2f);
495-
ImPlot3D::PlotLine("AngVel", velLineX.data(), velLineY.data(), velLineZ.data(), MAX_SAMPLES * 2, ImPlot3DLineFlags_Segments);
496-
ImPlot3D::EndPlot();
497-
}
498-
ImGui::SameLine();
499-
500427
{
501428
std::array<float, MAX_SAMPLES> t{}, avX{}, avY{}, avZ{}, maskSlash{}, maskStab{}, velLengthTriggered{};
502429
for (uint32_t j = 0; j < MAX_SAMPLES; ++j) {
@@ -533,7 +460,6 @@ class WeaponMotionAnalyser {
533460

534461
{
535462
std::array<float, MAX_SAMPLES> t{}, avX{}, avY{}, avZ{}, avddX{}, maskSlash{}, maskStab{};
536-
XrTime prevDelta = 0;
537463
for (uint32_t j = 0; j < MAX_SAMPLES; ++j) {
538464
const auto& s = m_rollingSamples[oldestIdx(j)];
539465
t[j] = static_cast<float>(j);
@@ -564,18 +490,6 @@ class WeaponMotionAnalyser {
564490
}
565491
ImGui::SameLine();
566492
}
567-
568-
// pass references to be manipulated in the drawSnapshot function
569-
glm::vec3& lastAngDir = m_debugLastAngDir;
570-
bool& angValid = m_debugAngValid;
571-
glm::vec3& lastLinDir = m_debugLastLinDir;
572-
bool& linValid = m_debugLinValid;
573-
574-
const glm::vec3 currAng = m_rollingSamples[m_lastSampleIdx].rotatedAngularVelocity();
575-
const glm::vec3 currLin = glm::inverse(m_rollingSamples[m_lastSampleIdx].rotation) * m_rollingSamples[m_lastSampleIdx].linearVelocity;
576-
577-
drawSnapshot("AngVel Snapshot", currAng, lastAngDir, angValid, 1.5f, ImVec4(1, 0, 0, 1), ImVec4(0.4f, 0.7f, 1, 0.25f));
578-
drawSnapshot("LinVel Snapshot", currLin, lastLinDir, linValid, 1.5f, ImVec4(0, 1, 0, 1), ImVec4(1, 0.7f, 0.2f, 0.25f));
579493
}
580494

581495
private:
@@ -597,8 +511,4 @@ class WeaponMotionAnalyser {
597511
uint32_t m_goodStabSampleCtr = 0;
598512
uint32_t m_badStabSampleCtr = 0;
599513

600-
mutable glm::vec3 m_debugLastAngDir = {1, 0, 0};
601-
mutable bool m_debugAngValid = false;
602-
mutable glm::vec3 m_debugLastLinDir = { 1, 0, 0 };
603-
mutable bool m_debugLinValid = false;
604-
};
514+
};

src/rendering/vulkan_imgui.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ RND_Renderer::ImGuiOverlay::ImGuiOverlay(VkCommandBuffer cb, VkExtent2D fbRes, V
4949
SetupImGuiStyle();
5050

5151
ImGui::GetIO().BackendFlags |= ImGuiBackendFlags_HasGamepad;
52-
ImPlot3D::CreateContext();
5352
ImPlot::CreateContext();
5453

5554
VkQueue queue = nullptr;
@@ -277,7 +276,6 @@ RND_Renderer::ImGuiOverlay::~ImGuiOverlay() {
277276

278277
ImGui_ImplVulkan_Shutdown();
279278
ImPlot::DestroyContext();
280-
ImPlot3D::DestroyContext();
281279
ImGui::DestroyContext();
282280
}
283281

0 commit comments

Comments
 (0)