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:
@@ -369,6 +369,23 @@ bool UsdSceneRenderer::SetCurrentAov(const pxr::TfToken& aov)
|
|||||||
return false;
|
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
|
// Camera State
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
|
|
||||||
@@ -6,6 +6,8 @@
|
|||||||
#include <pxr/usd/usd/timeCode.h>
|
#include <pxr/usd/usd/timeCode.h>
|
||||||
#include <pxr/imaging/glf/drawTarget.h>
|
#include <pxr/imaging/glf/drawTarget.h>
|
||||||
#include <pxr/usdImaging/usdImagingGL/engine.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/simpleLight.h>
|
||||||
#include <pxr/imaging/glf/simpleMaterial.h>
|
#include <pxr/imaging/glf/simpleMaterial.h>
|
||||||
#include <pxr/base/gf/vec3f.h>
|
#include <pxr/base/gf/vec3f.h>
|
||||||
@@ -187,6 +189,11 @@ public:
|
|||||||
pxr::TfTokenVector GetRendererAovs() const;
|
pxr::TfTokenVector GetRendererAovs() const;
|
||||||
bool SetCurrentAov(const pxr::TfToken& aov);
|
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; }
|
bool GetAAEnabled() const { return m_aaEnabled; }
|
||||||
void SetAAEnabled(bool enabled) { m_aaEnabled = enabled; }
|
void SetAAEnabled(bool enabled) { m_aaEnabled = enabled; }
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace UsdLayerManager {
|
namespace UsdLayerManager {
|
||||||
@@ -1084,6 +1085,10 @@ void ViewportTile::RenderCompactToolbar(int tileIndex)
|
|||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
if (ImGui::MenuItem("Renderer Settings..."))
|
||||||
|
m_showRendererSettings = true;
|
||||||
|
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1322,6 +1327,143 @@ void ViewportTile::Render(int tileIndex, ImVec2 pos, ImVec2 size,
|
|||||||
|
|
||||||
RenderContextMenu(tileIndex);
|
RenderContextMenu(tileIndex);
|
||||||
ImGui::EndChild();
|
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
|
} // namespace UsdLayerManager
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../core/UsdSceneRenderer.h"
|
#include "../core/UsdSceneRenderer.h"
|
||||||
#include "../core/ViewportCamera.h"
|
#include "../core/ViewportCamera.h"
|
||||||
@@ -184,6 +184,12 @@ private:
|
|||||||
// ── Per-frame interaction flags ──────────────────────────────────────────
|
// ── Per-frame interaction flags ──────────────────────────────────────────
|
||||||
bool m_wasClickedThisFrame = false;
|
bool m_wasClickedThisFrame = false;
|
||||||
bool m_wasHoveredThisFrame = 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
|
} // namespace UsdLayerManager
|
||||||
|
|||||||
Reference in New Issue
Block a user