scene_view concept
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user