From 205bf65ab3ad1e5f834d6c4fc1546613355bcbe3 Mon Sep 17 00:00:00 2001 From: indigo Date: Tue, 30 Jun 2026 04:34:53 +0800 Subject: [PATCH] Add renderer settings dialog with tab categories per delegate Surfaces each render delegate's settings (FLAG/INT/FLOAT/STRING) in a per-viewport floating dialog opened from the gear popup. Settings are grouped into tabs by key namespace prefix (split at ':'); unprefixed keys go into General. Changes apply immediately; Reset Defaults restores defValues. Settings list is cached per delegate to avoid TF_WARN flooding the log on every frame. Co-Authored-By: Claude Sonnet 4.6 --- src/core/UsdSceneRenderer.cpp | 17 ++++ src/core/UsdSceneRenderer.h | 9 ++- src/ui/ViewportTile.cpp | 142 ++++++++++++++++++++++++++++++++++ src/ui/ViewportTile.h | 8 +- 4 files changed, 174 insertions(+), 2 deletions(-) diff --git a/src/core/UsdSceneRenderer.cpp b/src/core/UsdSceneRenderer.cpp index 1c81496..9c9c1cf 100644 --- a/src/core/UsdSceneRenderer.cpp +++ b/src/core/UsdSceneRenderer.cpp @@ -369,6 +369,23 @@ bool UsdSceneRenderer::SetCurrentAov(const pxr::TfToken& aov) return false; } +pxr::UsdImagingGLRendererSettingsList UsdSceneRenderer::GetRendererSettingsList() const +{ + if (!m_renderer) return {}; + return m_renderer->GetRendererSettingsList(); +} + +pxr::VtValue UsdSceneRenderer::GetRendererSetting(const pxr::TfToken& id) const +{ + if (!m_renderer) return {}; + return m_renderer->GetRendererSetting(id); +} + +void UsdSceneRenderer::SetRendererSetting(const pxr::TfToken& id, const pxr::VtValue& v) +{ + if (m_renderer) m_renderer->SetRendererSetting(id, v); +} + // =========================================================================== // Camera State // =========================================================================== diff --git a/src/core/UsdSceneRenderer.h b/src/core/UsdSceneRenderer.h index 1700480..f27a16a 100644 --- a/src/core/UsdSceneRenderer.h +++ b/src/core/UsdSceneRenderer.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include #include #include @@ -187,6 +189,11 @@ public: pxr::TfTokenVector GetRendererAovs() const; bool SetCurrentAov(const pxr::TfToken& aov); + pxr::UsdImagingGLRendererSettingsList GetRendererSettingsList() const; + pxr::VtValue GetRendererSetting(const pxr::TfToken& id) const; + void SetRendererSetting(const pxr::TfToken& id, + const pxr::VtValue& value); + bool GetAAEnabled() const { return m_aaEnabled; } void SetAAEnabled(bool enabled) { m_aaEnabled = enabled; } diff --git a/src/ui/ViewportTile.cpp b/src/ui/ViewportTile.cpp index 82bb09a..e9a5bfd 100644 --- a/src/ui/ViewportTile.cpp +++ b/src/ui/ViewportTile.cpp @@ -16,6 +16,7 @@ #include #include +#include #include namespace UsdLayerManager { @@ -1084,6 +1085,10 @@ void ViewportTile::RenderCompactToolbar(int tileIndex) ImGui::EndMenu(); } + ImGui::Separator(); + if (ImGui::MenuItem("Renderer Settings...")) + m_showRendererSettings = true; + ImGui::EndPopup(); } } @@ -1322,6 +1327,143 @@ void ViewportTile::Render(int tileIndex, ImVec2 pos, ImVec2 size, RenderContextMenu(tileIndex); ImGui::EndChild(); + + if (m_showRendererSettings) + RenderRendererSettingsDialog(tileIndex); +} + +// --------------------------------------------------------------------------- +// RenderRendererSettingsDialog +// --------------------------------------------------------------------------- +void ViewportTile::RenderRendererSettingsDialog(int tileIndex) +{ + using namespace pxr; + std::string title = "Renderer Settings [" + + UsdSceneRenderer::GetRendererDisplayName(m_renderer.GetCurrentRendererId()) + + "]###RendererSettingsDlg_" + std::to_string(tileIndex); + + ImGui::SetNextWindowSize(ImVec2(520, 460), ImGuiCond_FirstUseEver); + // WindowPadding is captured by Begin(); pop it immediately after. + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(12.f, 12.f)); + bool open = ImGui::Begin(title.c_str(), &m_showRendererSettings, + ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoDocking); + ImGui::PopStyleVar(); + if (!open) { + ImGui::End(); + return; + } + + // ItemSpacing and FramePadding are read dynamically; push for content, pop before End. + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(8.f, 6.f)); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.f, 4.f)); + + // Cache the settings list per delegate — GetRendererSettingsList() calls TF_WARN + // for every unsupported setting type, so querying it every frame floods the log. + pxr::TfToken curId = m_renderer.GetCurrentRendererId(); + if (curId != m_cachedSettingsRendererId) { + m_cachedRendererSettings = m_renderer.GetRendererSettingsList(); + m_cachedSettingsRendererId = curId; + } + const auto& settings = m_cachedRendererSettings; + if (settings.empty()) { + ImVec2 sz = ImGui::GetContentRegionAvail(); + ImGui::SetCursorPos(ImVec2(sz.x * 0.5f - 120.f, sz.y * 0.5f - 8.f)); + ImGui::TextDisabled("This renderer exposes no settings."); + ImGui::PopStyleVar(2); + ImGui::End(); + return; + } + + // Group settings by namespace prefix (split key at first ':'). + // Keys without ':' go into "General". std::map keeps alphabetical order. + std::map> groups; + for (const auto& s : settings) { + std::string k = s.key.GetString(); + auto colon = k.find(':'); + std::string cat = (colon != std::string::npos) ? k.substr(0, colon) : "General"; + if (!cat.empty()) cat[0] = static_cast(toupper(static_cast(cat[0]))); + groups[cat].push_back(&s); + } + + bool singleGroup = (groups.size() == 1); + bool tabBarOpen = false; + if (!singleGroup) + tabBarOpen = ImGui::BeginTabBar("##rdrsettings_tabs"); + + auto renderGroup = [&](const std::vector& items) { + float tableH = ImGui::GetContentRegionAvail().y - 40.f; + if (tableH < 20.f) tableH = 20.f; + if (ImGui::BeginTable("##srows", 2, + ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_BordersInnerH | + ImGuiTableFlags_ScrollY, ImVec2(0, tableH))) + { + ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch, 0.55f); + ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch, 0.45f); + for (const auto* sp : items) { + const auto& s = *sp; + VtValue cur = m_renderer.GetRendererSetting(s.key); + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::AlignTextToFramePadding(); + ImGui::TextUnformatted(s.name.c_str()); + ImGui::TableSetColumnIndex(1); + ImGui::PushItemWidth(-1.f); + std::string wid = "##" + s.key.GetString(); + if (s.type == UsdImagingGLRendererSetting::TYPE_FLAG) { + bool v = cur.GetWithDefault(false); + if (ImGui::Checkbox(wid.c_str(), &v)) + m_renderer.SetRendererSetting(s.key, VtValue(v)); + } else if (s.type == UsdImagingGLRendererSetting::TYPE_INT) { + int v = cur.GetWithDefault(0); + if (ImGui::DragInt(wid.c_str(), &v)) + m_renderer.SetRendererSetting(s.key, VtValue(v)); + } else if (s.type == UsdImagingGLRendererSetting::TYPE_FLOAT) { + float v = cur.GetWithDefault(0.f); + if (ImGui::DragFloat(wid.c_str(), &v, 0.01f)) + m_renderer.SetRendererSetting(s.key, VtValue(v)); + } else if (s.type == UsdImagingGLRendererSetting::TYPE_STRING) { + std::string sv = cur.GetWithDefault(""); + char buf[256]; + strncpy(buf, sv.c_str(), sizeof(buf) - 1); + buf[sizeof(buf) - 1] = '\0'; + if (ImGui::InputText(wid.c_str(), buf, sizeof(buf)) && + ImGui::IsItemDeactivatedAfterEdit()) + m_renderer.SetRendererSetting(s.key, VtValue(std::string(buf))); + } + ImGui::PopItemWidth(); + } + ImGui::EndTable(); + } + }; + + if (singleGroup) { + renderGroup(groups.begin()->second); + } else if (tabBarOpen) { + // Non-"General" tabs first (alphabetical via std::map), then "General" last + for (const auto& [cat, items] : groups) { + if (cat == "General") continue; + if (ImGui::BeginTabItem(cat.c_str())) { + renderGroup(items); + ImGui::EndTabItem(); + } + } + auto genIt = groups.find("General"); + if (genIt != groups.end() && ImGui::BeginTabItem("General")) { + renderGroup(genIt->second); + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); + } + + ImGui::Separator(); + ImGui::Spacing(); + if (ImGui::Button("Reset Defaults")) { + for (const auto& s : settings) + m_renderer.SetRendererSetting(s.key, s.defValue); + } + + ImGui::PopStyleVar(2); + ImGui::End(); } } // namespace UsdLayerManager diff --git a/src/ui/ViewportTile.h b/src/ui/ViewportTile.h index db4ae4c..7c007ca 100644 --- a/src/ui/ViewportTile.h +++ b/src/ui/ViewportTile.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "../core/UsdSceneRenderer.h" #include "../core/ViewportCamera.h" @@ -184,6 +184,12 @@ private: // ── Per-frame interaction flags ────────────────────────────────────────── bool m_wasClickedThisFrame = false; bool m_wasHoveredThisFrame = false; + + // ── Renderer settings dialog ───────────────────────────────────────────── + bool m_showRendererSettings = false; + pxr::TfToken m_cachedSettingsRendererId; + pxr::UsdImagingGLRendererSettingsList m_cachedRendererSettings; + void RenderRendererSettingsDialog(int tileIndex); }; } // namespace UsdLayerManager