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 <noreply@anthropic.com>
This commit is contained in:
2026-06-30 04:34:53 +08:00
parent 862f3c9745
commit 205bf65ab3
4 changed files with 174 additions and 2 deletions
+17
View File
@@ -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
// ===========================================================================
+8 -1
View File
@@ -1,4 +1,4 @@
#pragma once
#pragma once
#include <glad/gl.h>
@@ -6,6 +6,8 @@
#include <pxr/usd/usd/timeCode.h>
#include <pxr/imaging/glf/drawTarget.h>
#include <pxr/usdImaging/usdImagingGL/engine.h>
#include <pxr/usdImaging/usdImagingGL/rendererSettings.h>
#include <pxr/base/vt/value.h>
#include <pxr/imaging/glf/simpleLight.h>
#include <pxr/imaging/glf/simpleMaterial.h>
#include <pxr/base/gf/vec3f.h>
@@ -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; }
+142
View File
@@ -16,6 +16,7 @@
#include <algorithm>
#include <cmath>
#include <map>
#include <string>
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<std::string, std::vector<const UsdImagingGLRendererSetting*>> 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<char>(toupper(static_cast<unsigned char>(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<const UsdImagingGLRendererSetting*>& 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<bool>(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<int>(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<float>(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<std::string>("");
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
+7 -1
View File
@@ -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