#ifdef ENABLE_EDITOR
#include "editor.h"
#include <algorithm>
#include "backend/imgui_backend.h"
#include "passes/fg_utils.h"
#include "passes/imgui/imgui.h"
#include "pipelines.h"
#include "renderer.h"
#include "scene/scene.h"
namespace editor {
void eval_render_size(u32 viewport_w, u32 viewport_h, rhi::Swapchain &swapchain, rhi::Extent2D &extent) {
rhi::Extent2D sc_extent = rhi::swapchain_extent(swapchain);
u32 w = (viewport_w > 0) ? viewport_w : sc_extent.width;
u32 h = (viewport_h > 0) ? viewport_h : sc_extent.height;
extent.width = std::max(w, 1u);
extent.height = std::max(h, 1u);
}
void handle_frame_begin(
Editor &e,
RenderData &rd,
rhi::Device &device,
rhi::Swapchain &swapchain,
FrameGraph &fg,
ImageHandle swapchain_target,
rhi::Extent2D &render_size,
Scene &scene,
Pipelines &pipelines,
PassTimings &timings,
u32 frame_slot
) {
begin_frame(e, rd);
if (e.viewport_resized && e.viewport_width > 0 && e.viewport_height > 0) {
rhi::queue_wait_idle(device);
eval_render_size(e.viewport_width, e.viewport_height, swapchain, render_size);
fg.overwrite_imported_image(swapchain_target, rhi::swapchain_image(swapchain, 0));
fg.compile(device, render_size);
Camera &cam = scene.cameras[scene.active_camera];
cam.aspect = static_cast<f32>(render_size.width) / static_cast<f32>(render_size.height);
e.viewport_resized = false;
}
if (reload_requested(e)) {
pipelines.reload();
}
timings.readback(device, frame_slot);
}
void record_present(
Editor &e,
Pipelines &pipelines,
rhi::ShaderCompiler &sc,
FrameGraph &fg,
rhi::Swapchain &swapchain,
const PresentTargets &targets,
PassTimings &timings
) {
imgui_pass::record(*fg.device, pipelines, sc, fg, rhi::swapchain_format(swapchain));
e.imgui_pipeline = &pipelines.get_render("ImGui");
Editor *ed = &e;
PassTimings *tm = &timings;
rhi::Swapchain *sw = &swapchain;
PresentTargets tg = targets;
auto &builder = fg.add_pass("Editor Present");
builder.read(tg.display, rhi::ResourceState::TextureSample);
builder.read(tg.irradiance, rhi::ResourceState::TextureSample);
builder.read(tg.distance, rhi::ResourceState::TextureSample);
builder.read(tg.id_blit, rhi::ResourceState::TextureSample);
for (u32 i = 0; i < Light::CASCADE_COUNT; ++i) {
builder.read(tg.cascade[i], rhi::ResourceState::TextureSample);
}
builder.write(tg.swapchain, rhi::ResourceState::ColorDraw).execute([ed, tm, sw, tg](PassContext &ctx) {
ctx.render_data->display = ctx.get_image(tg.display);
ctx.render_data->irr_atlas = ctx.get_image(tg.irradiance);
ctx.render_data->dis_atlas = ctx.get_image(tg.distance);
ctx.render_data->id_blit = ctx.get_image(tg.id_blit);
for (u32 i = 0; i < Light::CASCADE_COUNT; ++i) {
ctx.render_data->cascade[i] = ctx.get_image(tg.cascade[i]);
};
auto vs = ctx.image_view(tg.swapchain, {.aspect = rhi::ImageAspect::Color, .mip_count = 1});
rhi::AttachmentDesc color_att{};
color_att.img = &vs;
color_att.loadOp = rhi::LoadOp::CLEAR;
color_att.storeOp = rhi::StoreOp::STORE;
color_att.clearValue.color.float32[0] = 0.0f;
color_att.clearValue.color.float32[1] = 0.0f;
color_att.clearValue.color.float32[2] = 0.0f;
color_att.clearValue.color.float32[3] = 1.0f;
u32 pass_count;
const PassInspectorEntry *passes = tm->entries(pass_count);
editor::end_frame(*ed, *ctx.scene, *ctx.render_data, passes, pass_count);
bool draw_ui = false;
if (ed->imgui_pipeline != nullptr) {
draw_ui = imgui_backend::prepare(ctx);
}
rhi::RenderingInfo ri{};
ri.colorAttachments[0] = color_att;
ri.colorAttachmentCount = 1;
ri.width = (u32)rhi::swapchain_extent(*sw).width;
ri.height = (u32)rhi::swapchain_extent(*sw).height;
rhi::begin_rendering(ctx.cmd, ri);
if (draw_ui) {
imgui_backend::draw(ctx, *ed->imgui_pipeline, ri.width, ri.height);
}
rhi::end_rendering(ctx.cmd);
});
}
} // namespace editor
#endif // ENABLE_EDITOR