scene_view concept
This commit is contained in:
+47
-62
@@ -1,9 +1,11 @@
|
||||
#include <imgui.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
#include <glm/glm.hpp>
|
||||
#include <map>
|
||||
#include <sophia/application.hpp>
|
||||
#include <sophia/util/logger.hpp>
|
||||
#include <string>
|
||||
@@ -15,6 +17,7 @@
|
||||
#include "rendering/model_render_system.hpp"
|
||||
#include "rendering/render_context.hpp"
|
||||
#include "rendering/render_graph.hpp"
|
||||
#include "rendering/scene_renderer.hpp"
|
||||
#include "resources/mesh.hpp"
|
||||
#include "resources/render_target.hpp"
|
||||
#include "resources/resource_registry.hpp"
|
||||
@@ -43,35 +46,8 @@ std::vector<std::string> commandLineArgs;
|
||||
|
||||
constexpr ClearColor CLEAR_COLOR = {0.01f, 0.01f, 0.02f, 1.0f};
|
||||
|
||||
void beginColorPass(vk::CommandBuffer commandBuffer, vk::ImageView view,
|
||||
vk::Extent2D extent) {
|
||||
vk::ClearValue clearValue{};
|
||||
clearValue.color = vk::ClearColorValue{CLEAR_COLOR};
|
||||
|
||||
vk::RenderingAttachmentInfo colorAttachment{};
|
||||
colorAttachment.imageView = view;
|
||||
colorAttachment.imageLayout = vk::ImageLayout::eColorAttachmentOptimal;
|
||||
colorAttachment.loadOp = vk::AttachmentLoadOp::eClear;
|
||||
colorAttachment.storeOp = vk::AttachmentStoreOp::eStore;
|
||||
colorAttachment.clearValue = clearValue;
|
||||
|
||||
vk::RenderingInfo renderingInfo{};
|
||||
renderingInfo.renderArea = vk::Rect2D{{0, 0}, extent};
|
||||
renderingInfo.layerCount = 1;
|
||||
renderingInfo.colorAttachmentCount = 1;
|
||||
renderingInfo.pColorAttachments = &colorAttachment;
|
||||
|
||||
commandBuffer.beginRendering(renderingInfo);
|
||||
|
||||
vk::Viewport viewport{0.0f,
|
||||
0.0f,
|
||||
static_cast<float>(extent.width),
|
||||
static_cast<float>(extent.height),
|
||||
0.0f,
|
||||
1.0f};
|
||||
vk::Rect2D scissor{{0, 0}, extent};
|
||||
commandBuffer.setViewport(0, viewport);
|
||||
commandBuffer.setScissor(0, scissor);
|
||||
bool hasFlag(ClearFlags flags, ClearFlags flag) {
|
||||
return (static_cast<u8>(flags) & static_cast<u8>(flag)) != 0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -88,6 +64,8 @@ class Application::Impl {
|
||||
|
||||
void run() {
|
||||
ModelRenderSystem modelRenderSystem{device, renderContext};
|
||||
SceneRenderer sceneRenderer{this->application.sceneRegistry,
|
||||
this->resourceRegistry};
|
||||
ImGuiRenderer imguiRenderer{window, device, renderContext.getImageFormat(),
|
||||
renderContext.getImageCount(),
|
||||
this->resourceRegistry};
|
||||
@@ -106,6 +84,7 @@ class Application::Impl {
|
||||
auto& renderTargetPool = this->resourceRegistry.renderTargetPool;
|
||||
|
||||
PanelRegistry& panelRegistry = this->application.panelRegistry;
|
||||
const SceneViewRegistry& sceneViews = this->application.sceneViewRegistry;
|
||||
|
||||
imguiRenderer.setDefaultLayout(panelRegistry.getDefaultLayout());
|
||||
|
||||
@@ -128,17 +107,10 @@ class Application::Impl {
|
||||
// frame's work (or ImGui's references to the targets) is recorded.
|
||||
renderTargetPool.applyPendingResizes();
|
||||
|
||||
RenderTarget* sceneTarget =
|
||||
this->sceneTargetHandle.isValid()
|
||||
? &renderTargetPool.get(this->sceneTargetHandle)
|
||||
: nullptr;
|
||||
|
||||
vk::Extent2D extent = renderContext.getExtent();
|
||||
vk::Extent2D sceneExtent =
|
||||
sceneTarget ? sceneTarget->getExtent() : extent;
|
||||
FrameInfo frameInfo{frameIndex, elapsedTime, deltaTime,
|
||||
glm::vec2(static_cast<float>(sceneExtent.width),
|
||||
static_cast<float>(sceneExtent.height)),
|
||||
glm::vec2(static_cast<float>(extent.width),
|
||||
static_cast<float>(extent.height)),
|
||||
this->application.camera};
|
||||
this->application.onUpdate(frameInfo);
|
||||
this->application.camera.setProjection(
|
||||
@@ -166,31 +138,54 @@ class Application::Impl {
|
||||
this->drawCalls.end());
|
||||
this->drawCalls.clear();
|
||||
|
||||
if (sceneTarget) {
|
||||
Image& targetImage = sceneTarget->getImage();
|
||||
targetImage.transitionLayout(commandBuffer,
|
||||
vk::ImageLayout::eColorAttachmentOptimal);
|
||||
beginColorPass(commandBuffer, targetImage.getView(), sceneExtent);
|
||||
modelRenderSystem.render(commandBuffer, instances, frameInfo);
|
||||
commandBuffer.endRendering();
|
||||
targetImage.transitionLayout(commandBuffer,
|
||||
vk::ImageLayout::eShaderReadOnlyOptimal);
|
||||
}
|
||||
|
||||
RenderGraph graph;
|
||||
ImageRef backbuffer =
|
||||
graph.importImage(renderContext.getCurrentImage(), Access::Present);
|
||||
|
||||
std::map<RenderTargetHandle, ImageRef> viewTargets;
|
||||
for (SceneViewHandle handle : sceneViews.GetRenderQueue()) {
|
||||
const SceneView& view = sceneViews.get(handle);
|
||||
if (!this->application.sceneRegistry.isAlive(view.scene) ||
|
||||
!renderTargetPool.isAlive(view.target)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto [it, inserted] = viewTargets.try_emplace(view.target);
|
||||
if (inserted) {
|
||||
it->second =
|
||||
graph.importImage(renderTargetPool.get(view.target).getImage(),
|
||||
Access::SampledRead);
|
||||
}
|
||||
|
||||
const vec4& color = view.clearColor;
|
||||
graph.addPass(
|
||||
"scene view",
|
||||
[&](RenderGraph::PassBuilder& pass) {
|
||||
pass.writeColor(it->second,
|
||||
hasFlag(view.clearFlags, ClearFlags::Color)
|
||||
? vk::AttachmentLoadOp::eClear
|
||||
: vk::AttachmentLoadOp::eLoad,
|
||||
{color.r, color.g, color.b, color.a});
|
||||
},
|
||||
[&sceneRenderer, &sceneViews, handle](vk::CommandBuffer) {
|
||||
const SceneView& view = sceneViews.get(handle);
|
||||
if (view.camera) {
|
||||
sceneRenderer.render(view);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
graph.addPass(
|
||||
"main",
|
||||
[&](RenderGraph::PassBuilder& pass) {
|
||||
pass.writeColor(backbuffer, vk::AttachmentLoadOp::eClear,
|
||||
CLEAR_COLOR);
|
||||
for (const auto& [handle, target] : viewTargets) {
|
||||
pass.sample(target);
|
||||
}
|
||||
},
|
||||
[&](vk::CommandBuffer commandBuffer) {
|
||||
if (!sceneTarget) {
|
||||
modelRenderSystem.render(commandBuffer, instances, frameInfo);
|
||||
}
|
||||
modelRenderSystem.render(commandBuffer, instances, frameInfo);
|
||||
|
||||
imguiRenderer.endFrame(commandBuffer);
|
||||
});
|
||||
@@ -237,10 +232,6 @@ class Application::Impl {
|
||||
this->drawCalls.push_back({&mesh, transform});
|
||||
}
|
||||
|
||||
void setSceneTarget(RenderTargetHandle handle) {
|
||||
this->sceneTargetHandle = handle;
|
||||
}
|
||||
|
||||
ResourceRegistry& getResourceRegistry() { return resourceRegistry; }
|
||||
|
||||
private:
|
||||
@@ -253,8 +244,6 @@ class Application::Impl {
|
||||
|
||||
std::vector<std::unique_ptr<Mesh>> meshes;
|
||||
std::vector<ModelRenderSystem::MeshInstance> drawCalls;
|
||||
|
||||
RenderTargetHandle sceneTargetHandle = RenderTargetHandle::invalid();
|
||||
};
|
||||
|
||||
void Application::setCommandLineArgs(int argc, const char* const* argv) {
|
||||
@@ -281,10 +270,6 @@ void Application::pushMesh(std::vector<CanvasVertex> vertices,
|
||||
impl->pushMesh(std::move(vertices), std::move(indices));
|
||||
}
|
||||
|
||||
void Application::setSceneTarget(RenderTargetHandle handle) {
|
||||
impl->setSceneTarget(handle);
|
||||
}
|
||||
|
||||
void Application::clearMeshes() { impl->clearMeshes(); }
|
||||
|
||||
void Application::drawMesh(MeshHandle handle, const glm::mat4& transform) {
|
||||
|
||||
Reference in New Issue
Block a user