Files
sophia/editor/panels/viewport_panel.cpp
T
burkkyy 9d2b167f70 Add offscreen render targets and rename AssetRegistry to ResourceRegistry
Add a RenderTarget resource so the scene can render offscreen instead of
straight to the swapchain. The editor uses it to show the scene inside the
Viewport panel.

- Rename AssetRegistry to ResourceRegistry (AssetTraits -> ResourceTraits,
  assets() -> resources()) and move the pools from engine/src/assets to
  engine/src/resources. It now covers non-asset GPU resources as well.
- Replace loadMesh() with create<T>(...), and add create<RenderTarget>(),
  requestResize(), getExtent() and isAlive().
- Add RenderTarget and RenderTargetPool with RenderTargetHandle.
  Resizes are deferred and applied at the start of the next frame, when the
  GPU is idle.
- Add Application::setSceneTarget(). With no target set, the scene still
  renders to the swapchain. With a target set, the scene renders offscreen
  and the swapchain receives only the UI. Frame extent and camera projection
  follow the target's size.
- Add sophia::UI (Application::ui()) with image() and getTextureId() to draw
  a render target in an ImGui window, sizing the target to the available
  space. ImGuiRenderer now registers the target textures for this.
- ViewportPanel takes the UI and a target, and draws the scene image in place
  of the flat background fill.
- Update the testbed, the boids example, and the glossary for the rename.
2026-09-20 16:20:28 -07:00

47 lines
1.4 KiB
C++

#include "viewport_panel.hpp"
#include <imgui.h>
void ViewportPanel::onUpdate(const sophia::FrameInfo&) {
const struct {
const char* label;
GizmoMode mode;
} modes[] = {{"Move", GizmoMode::Move},
{"Rotate", GizmoMode::Rotate},
{"Scale", GizmoMode::Scale}};
for (const auto& entry : modes) {
if (ImGui::RadioButton(entry.label, gizmoMode == entry.mode)) {
gizmoMode = entry.mode;
}
ImGui::SameLine();
}
ImGui::Checkbox("Grid", &showGrid);
ImGui::Separator();
const ImVec2 origin = ImGui::GetCursorScreenPos();
const ImVec2 size = ImGui::GetContentRegionAvail();
const ImVec2 end(origin.x + size.x, origin.y + size.y);
ui.image(target);
ImDrawList* drawList = ImGui::GetWindowDrawList();
if (showGrid) {
constexpr float GRID_STEP = 40.0f;
const ImU32 gridColor = IM_COL32(255, 255, 255, 18);
for (float x = GRID_STEP; x < size.x; x += GRID_STEP) {
drawList->AddLine(ImVec2(origin.x + x, origin.y),
ImVec2(origin.x + x, end.y), gridColor);
}
for (float y = GRID_STEP; y < size.y; y += GRID_STEP) {
drawList->AddLine(ImVec2(origin.x, origin.y + y),
ImVec2(end.x, origin.y + y), gridColor);
}
}
ImGui::SetCursorScreenPos(ImVec2(origin.x + 8.0f, origin.y + 8.0f));
ImGui::TextDisabled("%.0f x %.0f", size.x, size.y);
}