scene_view concept

This commit is contained in:
2026-09-25 20:23:12 -07:00
parent 0d145f615d
commit 341249bb96
6 changed files with 173 additions and 73 deletions
+3 -10
View File
@@ -10,6 +10,7 @@
#include <sophia/math.hpp>
#include <sophia/resource_registry_ref.hpp>
#include <sophia/scene_registry.hpp>
#include <sophia/scene_view_registry.hpp>
#include <sophia/types.hpp>
#include <sophia/ui/debug_ui.hpp>
#include <sophia/ui/panel_registry.hpp>
@@ -46,6 +47,7 @@ class Application {
ResourceRegistryRef resources();
PanelRegistry& panels() { return this->panelRegistry; }
SceneRegistry& scenes() { return this->sceneRegistry; }
SceneViewRegistry& views() { return this->sceneViewRegistry; }
UI& ui() { return this->_ui; }
DebugUI& debugUI() { return this->_debugUI; }
@@ -58,16 +60,6 @@ class Application {
void drawMesh(MeshHandle handle, const glm::mat4& transform);
/**
* !TEMP !TODO remove this func eventually
* Chooses where the scene is rendered. An invalid handle (the default) means
* the swapchain; a target created with
* ResourceRegistryRef::create<RenderTarget>() redirects it offscreen, and the
* swapchain then only receives the UI. FrameInfo::currentFramebufferExtent
* and the camera projection follow the target's size.
*/
void setSceneTarget(RenderTargetHandle handle);
private:
friend class Canvas;
@@ -79,6 +71,7 @@ class Application {
PanelRegistry panelRegistry;
SceneRegistry sceneRegistry;
SceneViewRegistry sceneViewRegistry;
UI _ui;
DebugUI _debugUI;
+2
View File
@@ -37,10 +37,12 @@ class Mesh;
class Panel;
class RenderTarget;
class Scene;
struct SceneView;
using MeshHandle = Handle<Mesh>;
using PanelHandle = Handle<Panel>;
using RenderTargetHandle = Handle<RenderTarget>;
using SceneHandle = Handle<Scene>;
using SceneViewHandle = Handle<SceneView>;
} // namespace sophia
+34
View File
@@ -0,0 +1,34 @@
#pragma once
#include <sophia/entity.hpp>
#include <sophia/handles.hpp>
#include <sophia/math.hpp>
#include <sophia/scene.hpp>
namespace sophia {
enum class ClearFlags : u8 {
None = 0,
Color = 1 << 0,
Depth = 1 << 1,
Stencil = 1 << 2,
All = Color | Depth | Stencil
};
struct SceneView {
SceneHandle scene = INVALID_HANDLE;
RenderTargetHandle target = INVALID_HANDLE;
Entity camera;
vec4 viewport{0.0f, 0.0f, 1.0f, 1.0f};
vec4 clearColor{0.f, 0.f, 0.f, 1.f};
ClearFlags clearFlags = ClearFlags::All;
u32 priority = 0; // Lower priority renders first
u32 layerMask = 0xFFFFFFFF;
bool enabled = true; // Disabled views are kept but not rendered
};
} // namespace sophia
@@ -0,0 +1,86 @@
#pragma once
#include <algorithm>
#include <sophia/handles.hpp>
#include <sophia/scene_view.hpp>
#include <sophia/util/pool.hpp>
#include <utility>
#include <vector>
namespace sophia {
/**
* Every live SceneView. The application renders all enabled views each frame,
* in ascending priority order, before the UI.
*/
class SceneViewRegistry {
public:
SceneViewRegistry(const SceneViewRegistry&) = delete;
SceneViewRegistry& operator=(const SceneViewRegistry&) = delete;
SceneViewRegistry() = default;
~SceneViewRegistry() = default;
SceneViewHandle create(const SceneView& view = {}) {
isRenderQueueDirty = true;
return pool.create(view);
}
const SceneView& get(SceneViewHandle handle) const {
return pool.get(handle);
}
SceneView& get(SceneViewHandle handle) {
isRenderQueueDirty = true;
return pool.get(handle);
}
void release(SceneViewHandle handle) {
isRenderQueueDirty = true;
pool.release(handle);
}
bool isAlive(SceneViewHandle handle) const { return pool.isAlive(handle); }
u32 size() const { return pool.size(); }
template <typename Fn>
void forEach(Fn&& fn) {
isRenderQueueDirty = true;
pool.forEach(std::forward<Fn>(fn));
}
template <typename Fn>
void forEach(Fn&& fn) const {
pool.forEach(std::forward<Fn>(fn));
}
const std::vector<SceneViewHandle>& GetRenderQueue() const {
if (isRenderQueueDirty) {
rebuildRenderQueue();
}
return renderQueue;
}
private:
void rebuildRenderQueue() const {
renderQueue.clear();
pool.forEachWithHandle([&](SceneViewHandle handle, const SceneView& view) {
if (view.enabled) {
renderQueue.push_back(handle);
}
});
std::ranges::stable_sort(renderQueue, {}, [this](SceneViewHandle handle) {
return pool.get(handle).priority;
});
isRenderQueueDirty = false;
}
Pool<SceneView> pool{"SceneView"};
mutable std::vector<SceneViewHandle> renderQueue;
mutable bool isRenderQueueDirty = true;
};
} // namespace sophia