diff --git a/engine/core/include/engine.hpp b/engine/core/include/engine.hpp index 527ebc2..1280c3e 100755 --- a/engine/core/include/engine.hpp +++ b/engine/core/include/engine.hpp @@ -19,6 +19,7 @@ class App; class Scene; class Input; class Renderer; +class RenderTarget; class Physics; class ImGuiLayer; struct Timer; @@ -115,7 +116,7 @@ public: @param index Index of the window. Default is 0. @return Instance of the renderer. Will not be null. */ - Renderer* get_renderer(const int index = 0); + Renderer* get_renderer(); /** Get the physics system. @return Instance of the physics system. Will not be null. @@ -340,7 +341,7 @@ private: prism::Extent extent; bool quitRequested = false; - std::unique_ptr renderer; + RenderTarget* render_target; }; std::vector _windows; @@ -368,6 +369,7 @@ private: std::unique_ptr _input; std::unique_ptr _physics; + std::unique_ptr _renderer; std::vector _timers, _timersToRemove; diff --git a/engine/core/src/debug.cpp b/engine/core/src/debug.cpp index f5e23d8..bcbeec2 100644 --- a/engine/core/src/debug.cpp +++ b/engine/core/src/debug.cpp @@ -126,7 +126,7 @@ void draw_renderer() { float render_scale = render_options.render_scale; if(ImGui::DragFloat("Render Scale", &render_scale, 0.1f, 1.0f, 0.1f) && render_scale > 0.0f) { render_options.render_scale = render_scale; - engine->get_renderer()->resize(engine->get_renderer()->get_extent()); + engine->get_renderer()->recreate_all_render_targets(); } if(ImGui::InputInt("Shadow Resolution", &render_options.shadow_resolution)) { diff --git a/engine/core/src/engine.cpp b/engine/core/src/engine.cpp index 3ab6093..fd5e98c 100755 --- a/engine/core/src/engine.cpp +++ b/engine/core/src/engine.cpp @@ -107,8 +107,8 @@ Input* Engine::get_input() { return _input.get(); } -Renderer* Engine::get_renderer(const int index) { - return _windows[index].renderer.get(); +Renderer* Engine::get_renderer() { + return _renderer.get(); } Physics* Engine::get_physics() { @@ -406,6 +406,10 @@ void Engine::add_window(void* native_handle, const int identifier, const prism:: Expects(native_handle != nullptr); Expects(identifier >= 0); + if(identifier == 0) { + _renderer = std::make_unique(_gfx); + } + const auto drawable_extent = platform::get_window_drawable_size(identifier); _gfx->initialize_view(native_handle, identifier, drawable_extent.width, drawable_extent.height); @@ -413,9 +417,7 @@ void Engine::add_window(void* native_handle, const int identifier, const prism:: Window& window = _windows.emplace_back(); window.identifier = identifier; window.extent = extent; - window.renderer = std::make_unique(_gfx); - - window.renderer->resize(drawable_extent); + window.render_target = _renderer->allocate_render_target(drawable_extent); render_ready = true; } @@ -440,7 +442,7 @@ void Engine::resize(const int identifier, const prism::Extent extent) { const auto drawable_extent = platform::get_window_drawable_size(identifier); _gfx->recreate_view(identifier, drawable_extent.width, drawable_extent.height); - window->renderer->resize(drawable_extent); + _renderer->resize_render_target(*window->render_target, drawable_extent); if(identifier == 0) { if(_current_screen != nullptr) { @@ -752,7 +754,7 @@ void Engine::render(const int index) { if(index == 0) { if(_current_screen != nullptr && _current_screen->view_changed) { - _windows[0].renderer->update_screen(); + _renderer->update_screen(); _current_screen->view_changed = false; } @@ -763,8 +765,8 @@ void Engine::render(const int index) { _app->render(commandbuffer); - if(window->renderer != nullptr) - window->renderer->render(commandbuffer, _current_scene, index); + if(_renderer != nullptr) + _renderer->render(commandbuffer, _current_scene, *window->render_target, index); _gfx->submit(commandbuffer, index); } diff --git a/engine/renderer/CMakeLists.txt b/engine/renderer/CMakeLists.txt index 335c983..30dce1f 100755 --- a/engine/renderer/CMakeLists.txt +++ b/engine/renderer/CMakeLists.txt @@ -2,7 +2,6 @@ set(SRC include/renderer.hpp include/font.hpp include/pass.hpp - include/gaussianhelper.hpp include/shadowpass.hpp include/imguipass.hpp include/smaapass.hpp @@ -11,9 +10,9 @@ set(SRC include/dofpass.hpp include/frustum.hpp include/render_options.hpp + include/rendertarget.hpp src/renderer.cpp - src/gaussianhelper.cpp src/shadowpass.cpp src/imguipass.cpp src/smaapass.cpp diff --git a/engine/renderer/include/gaussianhelper.hpp b/engine/renderer/include/gaussianhelper.hpp deleted file mode 100755 index b00b131..0000000 --- a/engine/renderer/include/gaussianhelper.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "common.hpp" - -class GFX; -class GFXCommandBuffer; -class GFXFramebuffer; -class GFXPipeline; -class GFXRenderPass; -class GFXTexture; - -class GaussianHelper { -public: - GaussianHelper(GFX* gfx, const prism::Extent extent); - - GFXTexture* render(GFXCommandBuffer* commandBuffer,GFXTexture* source); - - GFXPipeline* pipeline = nullptr; - - GFXRenderPass* renderPass = nullptr; - - GFXTexture* texA = nullptr, *texB = nullptr; - GFXFramebuffer* fboA = nullptr, *fboB = nullptr; - -private: - prism::Extent extent; -}; diff --git a/engine/renderer/include/renderer.hpp b/engine/renderer/include/renderer.hpp index 71779d3..1a38007 100755 --- a/engine/renderer/include/renderer.hpp +++ b/engine/renderer/include/renderer.hpp @@ -11,6 +11,7 @@ #include "render_options.hpp" #include "path.hpp" #include "shadercompiler.hpp" +#include "rendertarget.hpp" namespace ui { class Screen; @@ -46,34 +47,22 @@ class Renderer { public: Renderer(GFX* gfx, const bool enable_imgui = true); ~Renderer(); - - void resize(const prism::Extent extent); - void resize_viewport(const prism::Extent extent); - + + RenderTarget* allocate_render_target(const prism::Extent extent); + void resize_render_target(RenderTarget& target, const prism::Extent extent); + void recreate_all_render_targets(); + void set_screen(ui::Screen* screen); void init_screen(ui::Screen* screen); void update_screen(); - void startCrossfade(); - void startSceneBlur(); - void stopSceneBlur(); - - float fade = 0.0f; - bool fading = false; - - bool blurring = false; - bool hasToStore = true; - int blurFrame = 0; - - GFXTexture* blurStore = nullptr; - struct ControllerContinuity { int elementOffset = 0; }; - void render(GFXCommandBuffer* command_buffer, Scene* scene, int index); + void render(GFXCommandBuffer* command_buffer, Scene* scene, RenderTarget& target, int index); - void render_screen(GFXCommandBuffer* commandBuffer, ui::Screen* screen, ControllerContinuity& continuity, RenderScreenOptions options = RenderScreenOptions()); + void render_screen(GFXCommandBuffer* commandBuffer, ui::Screen* screen, prism::Extent extent, ControllerContinuity& continuity, RenderScreenOptions options = RenderScreenOptions()); void render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Object camera_object, Camera& camera, prism::Extent extent, ControllerContinuity& continuity); void create_mesh_pipeline(Material& material); @@ -96,31 +85,8 @@ public: return nullptr; } - - GFXRenderPass* getOffscreenRenderPass() const { - return offscreenRenderPass; - } - - GFXTexture* offscreenColorTexture = nullptr; - GFXTexture* offscreenDepthTexture = nullptr; - - GFXTexture* viewportColorTexture = nullptr; - - bool viewport_mode = false; - prism::Extent viewport_extent; - bool gui_only_mode = false; - - prism::Extent get_extent() const { - return viewport_mode ? viewport_extent : extent; - } - - prism::Extent get_render_extent() const { - const auto extent = get_extent(); - - return {static_cast(std::max(int(extent.width * render_options.render_scale), 1)), - static_cast(std::max(int(extent.height * render_options.render_scale), 1))}; - } + GFXRenderPass* offscreenRenderPass = nullptr; std::unique_ptr shadow_pass; std::unique_ptr scene_capture; @@ -146,28 +112,21 @@ public: private: void createDummyTexture(); - void createOffscreenResources(); + void create_render_target_resources(RenderTarget& target); void createMeshPipeline(); void createPostPipeline(); void createFontPipeline(); void createSkyPipeline(); void createUIPipeline(); - void createGaussianResources(); void createBRDF(); void create_histogram_resources(); GFX* gfx = nullptr; - prism::Extent extent; + + std::vector> render_targets; ui::Screen* current_screen = nullptr; - // offscreen - GFXTexture* offscreenBackTexture = nullptr; - GFXFramebuffer* offscreenFramebuffer = nullptr; - GFXRenderPass* offscreenRenderPass = nullptr; - - GFXFramebuffer* viewportFramebuffer = nullptr; - // mesh GFXBuffer* sceneBuffer = nullptr; @@ -199,10 +158,7 @@ private: GFXTexture* average_luminance_texture = nullptr; std::unique_ptr smaaPass; - std::unique_ptr gHelper; std::unique_ptr dofPass; std::vector> passes; - - double current_render_scale = 1.0; }; diff --git a/engine/renderer/include/rendertarget.hpp b/engine/renderer/include/rendertarget.hpp new file mode 100755 index 0000000..03c1cad --- /dev/null +++ b/engine/renderer/include/rendertarget.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include "common.hpp" +#include "render_options.hpp" + +class GFXTexture; +class GFXFramebuffer; + +class RenderTarget { +public: + prism::Extent extent; + + prism::Extent get_render_extent() const { + return {static_cast(std::max(int(extent.width * render_options.render_scale), 1)), + static_cast(std::max(int(extent.height * render_options.render_scale), 1))}; + } + + // offscreen + GFXTexture* offscreenColorTexture = nullptr; + GFXTexture* offscreenDepthTexture = nullptr; + + GFXFramebuffer* offscreenFramebuffer = nullptr; + + // smaa + GFXTexture* edge_texture = nullptr; + GFXTexture* blend_texture = nullptr; + + GFXFramebuffer* edge_framebuffer = nullptr; + GFXFramebuffer* blend_framebuffer = nullptr; +}; diff --git a/engine/renderer/include/smaapass.hpp b/engine/renderer/include/smaapass.hpp index 9c7056d..d4c10e0 100755 --- a/engine/renderer/include/smaapass.hpp +++ b/engine/renderer/include/smaapass.hpp @@ -10,23 +10,21 @@ class GFXPipeline; class GFXRenderPass; class GFXTexture; class Renderer; +class RenderTarget; class SMAAPass { public: SMAAPass(GFX* gfx, Renderer* renderer); - void render(GFXCommandBuffer* command_buffer); + void create_render_target_resources(RenderTarget& target); - GFXTexture* edge_texture = nullptr; - GFXTexture* blend_texture = nullptr; + void render(GFXCommandBuffer* command_buffer, RenderTarget& target); private: void create_textures(); void create_render_pass(); void create_pipelines(); - void create_offscreen_resources(); - prism::Extent extent; Renderer* renderer = nullptr; GFXTexture* area_image = nullptr; @@ -36,8 +34,4 @@ private: GFXPipeline* edge_pipeline = nullptr; GFXPipeline* blend_pipeline = nullptr; - - GFXFramebuffer* edge_framebuffer = nullptr; - - GFXFramebuffer* blend_framebuffer = nullptr; }; diff --git a/engine/renderer/src/dofpass.cpp b/engine/renderer/src/dofpass.cpp index ce16718..a92e9d9 100755 --- a/engine/renderer/src/dofpass.cpp +++ b/engine/renderer/src/dofpass.cpp @@ -17,7 +17,8 @@ DoFPass::DoFPass(GFX* gfx, Renderer* renderer) : renderer(renderer) { renderpass = gfx->create_render_pass(renderPassInfo); - const auto extent = renderer->get_render_extent(); + //const auto extent = renderer->get_render_extent(); + const auto extent = prism::Extent(); GFXShaderConstant width_constant = {}; width_constant.value = extent.width; @@ -77,7 +78,9 @@ DoFPass::DoFPass(GFX* gfx, Renderer* renderer) : renderer(renderer) { } void DoFPass::render(GFXCommandBuffer* command_buffer, Scene&) { - const auto render_extent = renderer->get_render_extent(); + //const auto render_extent = renderer->get_render_extent(); + const auto extent = prism::Extent(); + const auto render_extent = prism::Extent(); // render far field GFXRenderPassBeginInfo beginInfo = {}; @@ -94,11 +97,11 @@ void DoFPass::render(GFXCommandBuffer* command_buffer, Scene&) { command_buffer->set_graphics_pipeline(pipeline); - command_buffer->bind_texture(renderer->offscreenColorTexture, 0); - command_buffer->bind_texture(renderer->offscreenDepthTexture, 1); + //command_buffer->bind_texture(renderer->offscreenColorTexture, 0); + //command_buffer->bind_texture(renderer->offscreenDepthTexture, 1); command_buffer->bind_texture(aperture_texture->handle, 3); - const auto extent = renderer->get_render_extent(); + //const auto extent = renderer->get_render_extent(); Vector4 params(render_options.depth_of_field_strength, 0.0, 0.0, 0.0); @@ -113,8 +116,8 @@ void DoFPass::render(GFXCommandBuffer* command_buffer, Scene&) { command_buffer->set_graphics_pipeline(pipeline); - command_buffer->bind_texture(renderer->offscreenColorTexture, 0); - command_buffer->bind_texture(renderer->offscreenDepthTexture, 1); + //command_buffer->bind_texture(renderer->offscreenColorTexture, 0); + //command_buffer->bind_texture(renderer->offscreenDepthTexture, 1); command_buffer->bind_texture(aperture_texture->handle, 2); params.y = 1; diff --git a/engine/renderer/src/gaussianhelper.cpp b/engine/renderer/src/gaussianhelper.cpp deleted file mode 100755 index c8ac1b4..0000000 --- a/engine/renderer/src/gaussianhelper.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include "gaussianhelper.hpp" - -#include "gfx_commandbuffer.hpp" -#include "gfx.hpp" - -GaussianHelper::GaussianHelper(GFX* gfx, const prism::Extent extent) : extent(extent) { - // render pass - GFXRenderPassCreateInfo renderPassInfo = {}; - renderPassInfo.label = "Gaussian"; - renderPassInfo.attachments.push_back(GFXPixelFormat::RGBA_32F); - - renderPass = gfx->create_render_pass(renderPassInfo); - - // pipeline - GFXGraphicsPipelineCreateInfo pipelineInfo = {}; - pipelineInfo.label = "Gaussian"; - pipelineInfo.shaders.vertex_src = file::Path("gaussian.vert"); - pipelineInfo.shaders.fragment_src = file::Path("gaussian.frag"); - - pipelineInfo.rasterization.primitive_type = GFXPrimitiveType::TriangleStrip; - - pipelineInfo.shader_input.bindings = { - {0, GFXBindingType::Texture}, - {1, GFXBindingType::PushConstant} - }; - - pipelineInfo.shader_input.push_constants = { - {sizeof(int), 0} - }; - - pipelineInfo.render_pass = renderPass; - - pipeline = gfx->create_graphics_pipeline(pipelineInfo); - - // resources - GFXTextureCreateInfo textureInfo = {}; - textureInfo.label = "Gaussian"; - textureInfo.width = extent.width; - textureInfo.height = extent.height; - textureInfo.format = GFXPixelFormat::RGBA_32F; - textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled; - textureInfo.samplingMode = SamplingMode::ClampToEdge; - - texA = gfx->create_texture(textureInfo); - texB = gfx->create_texture(textureInfo); - - GFXFramebufferCreateInfo info; - info.attachments = {texA}; - info.render_pass = renderPass; - - fboA = gfx->create_framebuffer(info); - - info.attachments = {texB}; - - fboB = gfx->create_framebuffer(info); -} - -GFXTexture* GaussianHelper::render(GFXCommandBuffer* commandBuffer, GFXTexture* source) { - bool horizontal = true, first_iteration = true; - int amount = 10; - for(int i = 0; i < amount; i++) { - GFXRenderPassBeginInfo info = {}; - info.framebuffer = horizontal ? fboA : fboB; - info.render_pass = renderPass; - info.render_area.extent = extent; - - commandBuffer->set_render_pass(info); - - commandBuffer->set_graphics_pipeline(pipeline); - - commandBuffer->memory_barrier(); - - int h = static_cast(horizontal); - commandBuffer->set_push_constant(&h, sizeof(int)); - commandBuffer->bind_texture(first_iteration ? source : (horizontal ? texB : texA), 0); - - commandBuffer->draw(0, 4, 0, 1); - - horizontal = !horizontal; - if (first_iteration) - first_iteration = false; - } - - return (horizontal ? texB : texA); -} diff --git a/engine/renderer/src/renderer.cpp b/engine/renderer/src/renderer.cpp index 697e02c..2b35b1c 100755 --- a/engine/renderer/src/renderer.cpp +++ b/engine/renderer/src/renderer.cpp @@ -13,7 +13,6 @@ #include "imguipass.hpp" #include "gfx.hpp" #include "log.hpp" -#include "gaussianhelper.hpp" #include "pass.hpp" #include "shadowpass.hpp" #include "smaapass.hpp" @@ -98,53 +97,85 @@ Renderer::Renderer(GFX* gfx, const bool enable_imgui) : gfx(gfx) { shadow_pass = std::make_unique(gfx); scene_capture = std::make_unique(gfx); + smaaPass = std::make_unique(gfx, this); if(enable_imgui) addPass(); createBRDF(); + + GFXRenderPassCreateInfo renderPassInfo = {}; + renderPassInfo.label = "Offscreen"; + renderPassInfo.attachments.push_back(GFXPixelFormat::RGBA_32F); + renderPassInfo.attachments.push_back(GFXPixelFormat::DEPTH_32F); + renderPassInfo.will_use_in_shader = true; + + offscreenRenderPass = gfx->create_render_pass(renderPassInfo); + + createMeshPipeline(); + createFontPipeline(); + createSkyPipeline(); } Renderer::~Renderer() {} -void Renderer::resize(const prism::Extent extent) { - this->extent = extent; - this->current_render_scale = render_options.render_scale; +RenderTarget* Renderer::allocate_render_target(const prism::Extent extent) { + auto target = std::make_unique(); + + resize_render_target(*target, extent); + + return render_targets.emplace_back(std::move(target)).get();; +} - if(!viewport_mode) { - createOffscreenResources(); - createMeshPipeline(); - createPostPipeline(); - createFontPipeline(); - createSkyPipeline(); - createUIPipeline(); - createGaussianResources(); - - smaaPass = std::make_unique(gfx, this); - dofPass = std::make_unique(gfx, this); +void Renderer::resize_render_target(RenderTarget& target, const prism::Extent extent) { + target.extent = extent; + + create_render_target_resources(target); + smaaPass->create_render_target_resources(target); + createPostPipeline(); + + GFXGraphicsPipelineCreateInfo pipelineInfo = {}; + pipelineInfo.label = "Text"; + + pipelineInfo.shaders.vertex_src = file::Path("text.vert"); + pipelineInfo.shaders.fragment_src = file::Path("text.frag"); + + pipelineInfo.rasterization.primitive_type = GFXPrimitiveType::TriangleStrip; + + pipelineInfo.blending.enable_blending = true; + pipelineInfo.blending.src_rgb = GFXBlendFactor::SrcAlpha; + pipelineInfo.blending.dst_rgb = GFXBlendFactor::OneMinusSrcColor; + + pipelineInfo.shader_input.bindings = { + {4, GFXBindingType::PushConstant}, + {0, GFXBindingType::StorageBuffer}, + {1, GFXBindingType::StorageBuffer}, + {2, GFXBindingType::StorageBuffer}, + {3, GFXBindingType::Texture} + }; + + pipelineInfo.shader_input.push_constants = { + {sizeof(UIPushConstant), 0} + }; + + textPipeline = gfx->create_graphics_pipeline(pipelineInfo); + + if(worldTextPipeline == nullptr) { + pipelineInfo.render_pass = offscreenRenderPass; + pipelineInfo.label = "Text World"; + pipelineInfo.depth.depth_mode = GFXDepthMode::LessOrEqual; + + worldTextPipeline = gfx->create_graphics_pipeline(pipelineInfo); } + + createUIPipeline(); for(auto& pass : passes) pass->resize(extent); } -void Renderer::resize_viewport(const prism::Extent extent) { - this->viewport_extent = extent; - this->current_render_scale = render_options.render_scale; +void Renderer::recreate_all_render_targets() { - createOffscreenResources(); - createMeshPipeline(); - createPostPipeline(); - createFontPipeline(); - createSkyPipeline(); - createUIPipeline(); - createGaussianResources(); - - smaaPass = std::make_unique(gfx, this); - dofPass = std::make_unique(gfx, this); - - for(auto& pass : passes) - pass->resize(get_render_extent()); } void Renderer::set_screen(ui::Screen* screen) { @@ -182,12 +213,6 @@ void Renderer::init_screen(ui::Screen* screen) { void Renderer::update_screen() { if(current_screen != nullptr) { - if(current_screen->blurs_background) { - startSceneBlur(); - } else { - stopSceneBlur(); - } - for(auto& element : current_screen->elements) { if(!element.background.image.empty()) element.background.texture = assetm->get(file::app_domain / element.background.image); @@ -195,210 +220,153 @@ void Renderer::update_screen() { } } -void Renderer::startCrossfade() { - // copy the current screen - gfx->copy_texture(offscreenColorTexture, offscreenBackTexture); +void Renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarget& target, int index) { + const auto extent = target.extent; + const auto render_extent = target.get_render_extent(); - fading = true; - fade = 1.0f; -} - -void Renderer::startSceneBlur() { - blurring = true; - hasToStore = true; -} - -void Renderer::stopSceneBlur() { - blurring = false; -} - -void Renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, int index) { - if(render_options.render_scale != current_render_scale) { - if(viewport_mode) - resize_viewport(viewport_extent); - else - resize(extent); - } + commandbuffer->push_group("Scene Rendering"); - const auto extent = get_extent(); - const auto render_extent = get_render_extent(); - - if(!gui_only_mode) { - commandbuffer->push_group("Scene Rendering"); - - GFXRenderPassBeginInfo beginInfo = {}; - beginInfo.framebuffer = offscreenFramebuffer; - beginInfo.render_pass = offscreenRenderPass; - beginInfo.render_area.extent = render_extent; - - bool hasToRender = true; - if(blurring && !hasToStore) - hasToRender = false; + GFXRenderPassBeginInfo beginInfo = {}; + beginInfo.framebuffer = target.offscreenFramebuffer; + beginInfo.render_pass = offscreenRenderPass; + beginInfo.render_area.extent = render_extent; - ControllerContinuity continuity; + ControllerContinuity continuity; - if(scene != nullptr && hasToRender) { - commandbuffer->push_group("Shadow Rendering"); - - shadow_pass->render(commandbuffer, *scene); - + if(scene != nullptr) { + commandbuffer->push_group("Shadow Rendering"); + + shadow_pass->render(commandbuffer, *scene); + + commandbuffer->pop_group(); + + if(render_options.enable_ibl) { + commandbuffer->push_group("Scene Capture"); + scene_capture->render(commandbuffer, scene); commandbuffer->pop_group(); - - if(render_options.enable_ibl) { - commandbuffer->push_group("Scene Capture"); - scene_capture->render(commandbuffer, scene); - commandbuffer->pop_group(); - } - - commandbuffer->set_render_pass(beginInfo); - - const auto& cameras = scene->get_all(); - for(auto& [obj, camera] : cameras) { - const int actual_width = render_extent.width / cameras.size(); - - const bool requires_limited_perspective = render_options.enable_depth_of_field; - if(requires_limited_perspective) { - camera.perspective = transform::perspective(radians(camera.fov), static_cast(actual_width) / static_cast(render_extent.height), camera.near, 100.0f); - } else { - camera.perspective = transform::infinite_perspective(radians(camera.fov), static_cast(actual_width) / static_cast(render_extent.height), camera.near); - } - - camera.view = inverse(scene->get(obj).model); - - Viewport viewport = {}; - viewport.x = (actual_width * 0); - viewport.width = actual_width; - viewport.height = render_extent.height; - - commandbuffer->set_viewport(viewport); - - commandbuffer->push_group("render camera"); - - render_camera(commandbuffer, *scene, obj, camera, get_render_extent(), continuity); - - commandbuffer->pop_group(); - } - } - - commandbuffer->pop_group(); - - commandbuffer->push_group("SMAA"); - - smaaPass->render(commandbuffer); - - commandbuffer->pop_group(); - - if(render_options.enable_depth_of_field) - dofPass->render(commandbuffer, *scene); - - if(!viewport_mode) { - beginInfo.framebuffer = nullptr; - beginInfo.render_pass = nullptr; - } else { - beginInfo.framebuffer = viewportFramebuffer; - beginInfo.render_pass = viewportRenderPass; } commandbuffer->set_render_pass(beginInfo); - Viewport viewport = {}; - viewport.width = render_extent.width; - viewport.height = render_extent.height; - - commandbuffer->set_viewport(viewport); - - commandbuffer->push_group("Post Processing"); - - commandbuffer->set_compute_pipeline(histogram_pipeline); - - commandbuffer->bind_texture(offscreenColorTexture, 0); - commandbuffer->bind_shader_buffer(histogram_buffer, 0, 1, sizeof(uint32_t) * 256); - - const float lum_range = render_options.max_luminance - render_options.min_luminance; - - Vector4 params = Vector4(render_options.min_luminance, 1.0f / lum_range, render_extent.width, render_extent.height); - - commandbuffer->set_push_constant(¶ms, sizeof(Vector4)); - - commandbuffer->dispatch(static_cast(std::ceil(render_extent.width / 16.0f)), - static_cast(std::ceil(render_extent.height / 16.0f)), 1); - - commandbuffer->set_compute_pipeline(histogram_average_pipeline); - - params = Vector4(render_options.min_luminance, lum_range, std::clamp(1.0f - std::exp(-(1.0f / 60.0f) * 1.1f), 0.0f, 1.0f), render_extent.width * render_extent.height); - - commandbuffer->set_push_constant(¶ms, sizeof(Vector4)); - - commandbuffer->bind_texture(average_luminance_texture, 0); - - commandbuffer->dispatch(1, 1, 1); - - commandbuffer->set_graphics_pipeline(viewport_mode ? renderToViewportPipeline : postPipeline); - - if(render_options.enable_depth_of_field) - commandbuffer->bind_texture(dofPass->normal_field, 1); - else - commandbuffer->bind_texture(offscreenColorTexture, 1); - - commandbuffer->bind_texture(offscreenBackTexture, 2); - commandbuffer->bind_texture(smaaPass->blend_texture, 3); - - if(auto texture = get_requested_texture(PassTextureType::SelectionSobel)) - commandbuffer->bind_texture(texture, 5); - else - commandbuffer->bind_texture(dummyTexture, 5); - - commandbuffer->bind_texture(average_luminance_texture, 6); - - if(render_options.enable_depth_of_field) - commandbuffer->bind_texture(dofPass->far_field, 7); - else - commandbuffer->bind_texture(dummyTexture, 7); - - PostPushConstants pc; - pc.options.x = render_options.enable_aa; - pc.options.y = fade; - pc.options.z = render_options.exposure; - - if(render_options.enable_depth_of_field) - pc.options.w = 2; - - pc.transform_ops.x = (int)render_options.display_color_space; - pc.transform_ops.y = (int)render_options.tonemapping; - - const auto [width, height] = render_extent; - pc.viewport = Vector4(1.0f / static_cast(width), 1.0f / static_cast(height), width, height); - - commandbuffer->set_push_constant(&pc, sizeof(PostPushConstants)); - - if(fading) { - if(fade > 0.0f) - fade -= 0.1f; - else if(fade <= 0.0f) { - fading = false; - fade = 0.0f; + const auto& cameras = scene->get_all(); + for(auto& [obj, camera] : cameras) { + const int actual_width = render_extent.width / cameras.size(); + + const bool requires_limited_perspective = render_options.enable_depth_of_field; + if(requires_limited_perspective) { + camera.perspective = transform::perspective(radians(camera.fov), static_cast(actual_width) / static_cast(render_extent.height), camera.near, 100.0f); + } else { + camera.perspective = transform::infinite_perspective(radians(camera.fov), static_cast(actual_width) / static_cast(render_extent.height), camera.near); } + + camera.view = inverse(scene->get(obj).model); + + Viewport viewport = {}; + viewport.x = (actual_width * 0); + viewport.width = actual_width; + viewport.height = render_extent.height; + + commandbuffer->set_viewport(viewport); + + commandbuffer->push_group("render camera"); + + render_camera(commandbuffer, *scene, obj, camera, render_extent, continuity); + + commandbuffer->pop_group(); } - - commandbuffer->draw(0, 4, 0, 1); - - commandbuffer->pop_group(); - - if(current_screen != nullptr) - render_screen(commandbuffer, current_screen, continuity); - } else { - GFXRenderPassBeginInfo beginInfo = {}; - beginInfo.render_area.extent = extent; - - commandbuffer->set_render_pass(beginInfo); - - Viewport viewport = {}; - viewport.width = extent.width; - viewport.height = extent.height; - - commandbuffer->set_viewport(viewport); } + commandbuffer->pop_group(); + + commandbuffer->push_group("SMAA"); + + smaaPass->render(commandbuffer, target); + + commandbuffer->pop_group(); + + if(render_options.enable_depth_of_field) + dofPass->render(commandbuffer, *scene); + + beginInfo.framebuffer = nullptr; + beginInfo.render_pass = nullptr; + + commandbuffer->set_render_pass(beginInfo); + + Viewport viewport = {}; + viewport.width = render_extent.width; + viewport.height = render_extent.height; + + commandbuffer->set_viewport(viewport); + + commandbuffer->push_group("Post Processing"); + + commandbuffer->set_compute_pipeline(histogram_pipeline); + + commandbuffer->bind_texture(target.offscreenColorTexture, 0); + commandbuffer->bind_shader_buffer(histogram_buffer, 0, 1, sizeof(uint32_t) * 256); + + const float lum_range = render_options.max_luminance - render_options.min_luminance; + + Vector4 params = Vector4(render_options.min_luminance, 1.0f / lum_range, render_extent.width, render_extent.height); + + commandbuffer->set_push_constant(¶ms, sizeof(Vector4)); + + commandbuffer->dispatch(static_cast(std::ceil(render_extent.width / 16.0f)), + static_cast(std::ceil(render_extent.height / 16.0f)), 1); + + commandbuffer->set_compute_pipeline(histogram_average_pipeline); + + params = Vector4(render_options.min_luminance, lum_range, std::clamp(1.0f - std::exp(-(1.0f / 60.0f) * 1.1f), 0.0f, 1.0f), render_extent.width * render_extent.height); + + commandbuffer->set_push_constant(¶ms, sizeof(Vector4)); + + commandbuffer->bind_texture(average_luminance_texture, 0); + + commandbuffer->dispatch(1, 1, 1); + + commandbuffer->set_graphics_pipeline(postPipeline); + + if(render_options.enable_depth_of_field) + commandbuffer->bind_texture(dofPass->normal_field, 1); + else + commandbuffer->bind_texture(target.offscreenColorTexture, 1); + + commandbuffer->bind_texture(target.blend_texture, 3); + + if(auto texture = get_requested_texture(PassTextureType::SelectionSobel)) + commandbuffer->bind_texture(texture, 5); + else + commandbuffer->bind_texture(dummyTexture, 5); + + commandbuffer->bind_texture(average_luminance_texture, 6); + + if(render_options.enable_depth_of_field) + commandbuffer->bind_texture(dofPass->far_field, 7); + else + commandbuffer->bind_texture(dummyTexture, 7); + + PostPushConstants pc; + pc.options.x = render_options.enable_aa; + pc.options.z = render_options.exposure; + + if(render_options.enable_depth_of_field) + pc.options.w = 2; + + pc.transform_ops.x = (int)render_options.display_color_space; + pc.transform_ops.y = (int)render_options.tonemapping; + + const auto [width, height] = render_extent; + pc.viewport = Vector4(1.0f / static_cast(width), 1.0f / static_cast(height), width, height); + + commandbuffer->set_push_constant(&pc, sizeof(PostPushConstants)); + + commandbuffer->draw(0, 4, 0, 1); + + commandbuffer->pop_group(); + + if(current_screen != nullptr) + render_screen(commandbuffer, current_screen, extent, continuity); + commandbuffer->push_group("Extra Passes"); for(auto& pass : passes) @@ -532,7 +500,7 @@ void Renderer::render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Obj options.render_world = true; options.mvp = camera.perspective * camera.view * scene.get(obj).model; - render_screen(command_buffer, screen.screen, continuity, options); + render_screen(command_buffer, screen.screen, extent, continuity, options); } SkyPushConstant pc; @@ -558,7 +526,7 @@ void Renderer::render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Obj gfx->copy_buffer(sceneBuffer, &sceneInfo, 0, sizeof(SceneInformation)); } -void Renderer::render_screen(GFXCommandBuffer *commandbuffer, ui::Screen* screen, ControllerContinuity& continuity, RenderScreenOptions options) { +void Renderer::render_screen(GFXCommandBuffer *commandbuffer, ui::Screen* screen, prism::Extent extent, ControllerContinuity& continuity, RenderScreenOptions options) { std::array instances; std::vector elementInstances; std::array stringInstances; @@ -636,7 +604,6 @@ void Renderer::render_screen(GFXCommandBuffer *commandbuffer, ui::Screen* screen gfx->copy_buffer(screen->instance_buffer, stringInstances.data(), 0, sizeof(StringInstance) * 50); gfx->copy_buffer(screen->elements_buffer, elementInstances.data(), sizeof(ElementInstance) * continuity.elementOffset, sizeof(ElementInstance) * elementInstances.size()); - const auto extent = get_render_extent(); const Vector2 windowSize = {static_cast(extent.width), static_cast(extent.height)}; for(auto [i, element] : utility::enumerate(screen->elements)) { @@ -777,22 +744,8 @@ void Renderer::createDummyTexture() { gfx->copy_texture(dummyTexture, tex, sizeof(tex)); } -void Renderer::createOffscreenResources() { - GFXRenderPassCreateInfo renderPassInfo = {}; - renderPassInfo.label = "Offscreen"; - renderPassInfo.attachments.push_back(GFXPixelFormat::RGBA_32F); - renderPassInfo.attachments.push_back(GFXPixelFormat::DEPTH_32F); - renderPassInfo.will_use_in_shader = true; - - offscreenRenderPass = gfx->create_render_pass(renderPassInfo); - - renderPassInfo = {}; - renderPassInfo.label = "Offscreen Unorm"; - renderPassInfo.attachments = {GFXPixelFormat::RGBA8_UNORM}; - - unormRenderPass = gfx->create_render_pass(renderPassInfo); - - const auto extent = get_render_extent(); +void Renderer::create_render_target_resources(RenderTarget& target) { + const auto extent = target.get_render_extent(); GFXTextureCreateInfo textureInfo = {}; textureInfo.label = "Offscreen Color"; @@ -802,45 +755,57 @@ void Renderer::createOffscreenResources() { textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled; textureInfo.samplingMode = SamplingMode::ClampToEdge; - offscreenColorTexture = gfx->create_texture(textureInfo); - - textureInfo.label = "Offscreen Back"; - offscreenBackTexture = gfx->create_texture(textureInfo); + target.offscreenColorTexture = gfx->create_texture(textureInfo); textureInfo.label = "Offscreen Depth"; textureInfo.format = GFXPixelFormat::DEPTH_32F; - offscreenDepthTexture = gfx->create_texture(textureInfo); + target.offscreenDepthTexture = gfx->create_texture(textureInfo); GFXFramebufferCreateInfo framebufferInfo = {}; framebufferInfo.render_pass = offscreenRenderPass; - framebufferInfo.attachments.push_back(offscreenColorTexture); - framebufferInfo.attachments.push_back(offscreenDepthTexture); + framebufferInfo.attachments.push_back(target.offscreenColorTexture); + framebufferInfo.attachments.push_back(target.offscreenDepthTexture); - offscreenFramebuffer = gfx->create_framebuffer(framebufferInfo); - - if(viewport_mode) { - GFXRenderPassCreateInfo renderPassInfo = {}; - renderPassInfo.label = "Viewport"; - renderPassInfo.attachments.push_back(GFXPixelFormat::RGBA8_UNORM); - renderPassInfo.will_use_in_shader = true; - - viewportRenderPass = gfx->create_render_pass(renderPassInfo); - - GFXTextureCreateInfo textureInfo = {}; - textureInfo.label = "Viewport Color"; - textureInfo.width = extent.width; - textureInfo.height = extent.height; - textureInfo.format = GFXPixelFormat::RGBA8_UNORM; - textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled; - textureInfo.samplingMode = SamplingMode::ClampToEdge; - - viewportColorTexture = gfx->create_texture(textureInfo); - - framebufferInfo.render_pass = viewportRenderPass; - framebufferInfo.attachments = {viewportColorTexture}; - - viewportFramebuffer = gfx->create_framebuffer(framebufferInfo); + target.offscreenFramebuffer = gfx->create_framebuffer(framebufferInfo); + + GFXGraphicsPipelineCreateInfo pipelineInfo = {}; + pipelineInfo.label = "Post"; + + pipelineInfo.shaders.vertex_src = file::Path("post.vert"); + pipelineInfo.shaders.fragment_src = file::Path("post.frag"); + + pipelineInfo.shader_input.bindings = { + {4, GFXBindingType::PushConstant}, + {1, GFXBindingType::Texture}, + {2, GFXBindingType::Texture}, + {3, GFXBindingType::Texture}, + {5, GFXBindingType::Texture}, + {6, GFXBindingType::Texture}, + {7, GFXBindingType::Texture} + }; + + pipelineInfo.shader_input.push_constants = { + {sizeof(PostPushConstants), 0} + }; + + postPipeline = gfx->create_graphics_pipeline(pipelineInfo); + + if(renderToTexturePipeline == nullptr) { + pipelineInfo.label = "Render to Texture"; + pipelineInfo.render_pass = offscreenRenderPass; + + renderToTexturePipeline = gfx->create_graphics_pipeline(pipelineInfo); + + pipelineInfo.label = "Render to Texture (Unorm)"; + pipelineInfo.render_pass = unormRenderPass; + + renderToUnormTexturePipeline = gfx->create_graphics_pipeline(pipelineInfo); + + pipelineInfo.label = "Render to Viewport"; + pipelineInfo.render_pass = viewportRenderPass; + + renderToViewportPipeline = gfx->create_graphics_pipeline(pipelineInfo); } } @@ -851,10 +816,10 @@ void Renderer::createMeshPipeline() { void Renderer::createPostPipeline() { GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "Post"; - + pipelineInfo.shaders.vertex_src = file::Path("post.vert"); pipelineInfo.shaders.fragment_src = file::Path("post.frag"); - + pipelineInfo.shader_input.bindings = { {4, GFXBindingType::PushConstant}, {1, GFXBindingType::Texture}, @@ -864,16 +829,16 @@ void Renderer::createPostPipeline() { {6, GFXBindingType::Texture}, {7, GFXBindingType::Texture} }; - + pipelineInfo.shader_input.push_constants = { {sizeof(PostPushConstants), 0} }; - + postPipeline = gfx->create_graphics_pipeline(pipelineInfo); - + pipelineInfo.label = "Render to Texture"; pipelineInfo.render_pass = offscreenRenderPass; - + renderToTexturePipeline = gfx->create_graphics_pipeline(pipelineInfo); pipelineInfo.label = "Render to Texture (Unorm)"; @@ -883,7 +848,7 @@ void Renderer::createPostPipeline() { pipelineInfo.label = "Render to Viewport"; pipelineInfo.render_pass = viewportRenderPass; - + renderToViewportPipeline = gfx->create_graphics_pipeline(pipelineInfo); } @@ -901,38 +866,6 @@ void Renderer::createFontPipeline() { instanceAlignment = (int)gfx->get_alignment(sizeof(GlyphInstance) * maxInstances); - GFXGraphicsPipelineCreateInfo pipelineInfo = {}; - pipelineInfo.label = "Text"; - - pipelineInfo.shaders.vertex_src = file::Path("text.vert"); - pipelineInfo.shaders.fragment_src = file::Path("text.frag"); - - pipelineInfo.rasterization.primitive_type = GFXPrimitiveType::TriangleStrip; - - pipelineInfo.blending.enable_blending = true; - pipelineInfo.blending.src_rgb = GFXBlendFactor::SrcAlpha; - pipelineInfo.blending.dst_rgb = GFXBlendFactor::OneMinusSrcColor; - - pipelineInfo.shader_input.bindings = { - {4, GFXBindingType::PushConstant}, - {0, GFXBindingType::StorageBuffer}, - {1, GFXBindingType::StorageBuffer}, - {2, GFXBindingType::StorageBuffer}, - {3, GFXBindingType::Texture} - }; - - pipelineInfo.shader_input.push_constants = { - {sizeof(UIPushConstant), 0} - }; - - textPipeline = gfx->create_graphics_pipeline(pipelineInfo); - - pipelineInfo.render_pass = offscreenRenderPass; - pipelineInfo.label = "Text World"; - pipelineInfo.depth.depth_mode = GFXDepthMode::LessOrEqual; - - worldTextPipeline = gfx->create_graphics_pipeline(pipelineInfo); - GFXTextureCreateInfo textureInfo = {}; textureInfo.label = "UI Font"; textureInfo.width = font.width; @@ -1006,23 +939,6 @@ void Renderer::createUIPipeline() { worldGeneralPipeline = gfx->create_graphics_pipeline(pipelineInfo); } -void Renderer::createGaussianResources() { - const auto extent = get_render_extent(); - - gHelper = std::make_unique(gfx, extent); - - GFXTextureCreateInfo textureInfo = {}; - textureInfo.label = "Blur Store"; - textureInfo.width = extent.width; - textureInfo.height = extent.height; - textureInfo.format = GFXPixelFormat::RGBA_32F; - textureInfo.usage = GFXTextureUsage::Sampled; - - blurStore = gfx->create_texture(textureInfo); - - hasToStore = true; -} - void Renderer::createBRDF() { GFXRenderPassCreateInfo renderPassInfo = {}; renderPassInfo.label = "BRDF Gen"; diff --git a/engine/renderer/src/smaapass.cpp b/engine/renderer/src/smaapass.cpp index c654714..79ab730 100755 --- a/engine/renderer/src/smaapass.cpp +++ b/engine/renderer/src/smaapass.cpp @@ -9,20 +9,45 @@ #include #include -SMAAPass::SMAAPass(GFX* gfx, Renderer* renderer) : renderer(renderer), extent(renderer->get_render_extent()) { +SMAAPass::SMAAPass(GFX* gfx, Renderer* renderer) : renderer(renderer) { Expects(gfx != nullptr); Expects(renderer != nullptr); create_textures(); create_render_pass(); create_pipelines(); - create_offscreen_resources(); } -void SMAAPass::render(GFXCommandBuffer* command_buffer) { +void SMAAPass::create_render_target_resources(RenderTarget& target) { + auto gfx = engine->get_gfx(); + + GFXTextureCreateInfo textureInfo = {}; + textureInfo.label = "SMAA Edge"; + textureInfo.width = target.extent.width; + textureInfo.height = target.extent.height; + textureInfo.format = GFXPixelFormat::R16G16B16A16_SFLOAT; + textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled; + + target.edge_texture = gfx->create_texture(textureInfo); + + textureInfo.label = "SMAA Blend"; + target.blend_texture = gfx->create_texture(textureInfo); + + GFXFramebufferCreateInfo framebufferInfo = {}; + framebufferInfo.attachments = {target.edge_texture}; + framebufferInfo.render_pass = render_pass; + + target.edge_framebuffer = gfx->create_framebuffer(framebufferInfo); + + framebufferInfo.attachments = {target.blend_texture}; + + target.blend_framebuffer = gfx->create_framebuffer(framebufferInfo); +} + +void SMAAPass::render(GFXCommandBuffer* command_buffer, RenderTarget& target) { GFXRenderPassBeginInfo beginInfo = {}; beginInfo.clear_color.a = 0.0f; - beginInfo.render_area.extent = extent; + beginInfo.render_area.extent = target.extent; beginInfo.render_pass = render_pass; struct PushConstant { @@ -30,37 +55,37 @@ void SMAAPass::render(GFXCommandBuffer* command_buffer) { Matrix4x4 correction_matrix; } pc; - pc.viewport = Vector4(1.0f / static_cast(extent.width), 1.0f / static_cast(extent.height), extent.width, extent.height); + pc.viewport = Vector4(1.0f / static_cast(target.extent.width), 1.0f / static_cast(target.extent.height), target.extent.width, target.extent.height); // edge { - beginInfo.framebuffer = edge_framebuffer; + beginInfo.framebuffer = target.edge_framebuffer; command_buffer->set_render_pass(beginInfo); Viewport viewport = {}; - viewport.width = extent.width; - viewport.height = extent.height; + viewport.width = target.extent.width; + viewport.height = target.extent.height; command_buffer->set_viewport(viewport); command_buffer->set_graphics_pipeline(edge_pipeline); command_buffer->set_push_constant(&pc, sizeof(PushConstant)); - command_buffer->bind_texture(renderer->offscreenColorTexture, 0); // color - command_buffer->bind_texture(renderer->offscreenDepthTexture, 1); // depth + command_buffer->bind_texture(target.offscreenColorTexture, 0); // color + command_buffer->bind_texture(target.offscreenDepthTexture, 1); // depth command_buffer->draw(0, 3, 0, 1); } // blend { - beginInfo.framebuffer = blend_framebuffer; + beginInfo.framebuffer = target.blend_framebuffer; command_buffer->set_render_pass(beginInfo); command_buffer->set_graphics_pipeline(blend_pipeline); command_buffer->set_push_constant(&pc, sizeof(PushConstant)); - command_buffer->bind_texture(edge_texture, 0); + command_buffer->bind_texture(target.edge_texture, 0); command_buffer->bind_texture(area_image, 1); command_buffer->bind_texture(search_image, 3); @@ -136,29 +161,3 @@ void SMAAPass::create_pipelines() { blend_pipeline = gfx->create_graphics_pipeline(createInfo); } - -void SMAAPass::create_offscreen_resources() { - auto gfx = engine->get_gfx(); - - GFXTextureCreateInfo textureInfo = {}; - textureInfo.label = "SMAA Edge"; - textureInfo.width = extent.width; - textureInfo.height = extent.height; - textureInfo.format = GFXPixelFormat::R16G16B16A16_SFLOAT; - textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled; - - edge_texture = gfx->create_texture(textureInfo); - - textureInfo.label = "SMAA Blend"; - blend_texture = gfx->create_texture(textureInfo); - - GFXFramebufferCreateInfo framebufferInfo = {}; - framebufferInfo.attachments = {edge_texture}; - framebufferInfo.render_pass = render_pass; - - edge_framebuffer = gfx->create_framebuffer(framebufferInfo); - - framebufferInfo.attachments = {blend_texture}; - - blend_framebuffer = gfx->create_framebuffer(framebufferInfo); -} diff --git a/tools/common/include/commoneditor.hpp b/tools/common/include/commoneditor.hpp index adde4f4..df49d60 100755 --- a/tools/common/include/commoneditor.hpp +++ b/tools/common/include/commoneditor.hpp @@ -129,7 +129,7 @@ public: virtual void asset_selected([[maybe_unused]] std::filesystem::path path, [[maybe_unused]] AssetType type) {} void createDockArea(); - void drawViewport(Renderer& renderer); + void drawViewport(); void drawAssets(); // options @@ -335,6 +335,8 @@ private: void edit_asset_mesh(const char* name, AssetPtr& asset); void edit_asset_texture(const char* name, AssetPtr& asset); void edit_asset_material(const char* name, AssetPtr& asset); + + std::unordered_map viewport_render_targets; }; inline void editPath(const char* label, std::string& path, bool editable = true, const std::function on_selected = nullptr) { diff --git a/tools/common/src/commoneditor.cpp b/tools/common/src/commoneditor.cpp index 1167a6a..6118001 100755 --- a/tools/common/src/commoneditor.cpp +++ b/tools/common/src/commoneditor.cpp @@ -89,8 +89,6 @@ CommonEditor::CommonEditor(std::string id) : id(id) { } void CommonEditor::initialize_render() { - engine->get_renderer()->gui_only_mode = true; - load_thumbnail_cache(); } @@ -705,15 +703,26 @@ void CommonEditor::createDockArea() { ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_PassthruCentralNode); } -void CommonEditor::drawViewport(Renderer& renderer) { +void CommonEditor::drawViewport() { const auto size = ImGui::GetContentRegionAvail(); const auto real_size = ImVec2(size.x * platform::get_window_dpi(0), size.y * platform::get_window_dpi(0)); if(real_size.x <= 0 || real_size.y <= 0) return; - if(real_size.x != renderer.viewport_extent.width || real_size.y != renderer.viewport_extent.height) - renderer.resize_viewport(real_size); + auto window_id = ImGui::GetCurrentWindow()->ID; + + RenderTarget* target = nullptr; + if(viewport_render_targets.count(window_id)) { + target = viewport_render_targets[window_id]; + + if(real_size.x != target->extent.width || real_size.y != target->extent.height) + engine->get_renderer()->resize_render_target(*target, real_size); + } else { + target = engine->get_renderer()->allocate_render_target(real_size); + + viewport_render_targets[window_id] = target; + } viewport_width = size.x; viewport_height = size.y; @@ -724,7 +733,7 @@ void CommonEditor::drawViewport(Renderer& renderer) { viewport_x = mouse_pos.x - real_pos.x; viewport_y = mouse_pos.y - real_pos.y; - ImGui::Image((ImTextureID)renderer.viewportColorTexture, size); + ImGui::Image((ImTextureID)target->offscreenColorTexture, size); accepting_viewport_input = ImGui::IsWindowHovered(); @@ -974,7 +983,7 @@ GFXTexture* CommonEditor::generate_common_preview(Scene& scene, const Vector3 ca GFXFramebufferCreateInfo framebuffer_create_info = {}; framebuffer_create_info.attachments = {offscreen_color_texture, offscreen_depth_texture}; - framebuffer_create_info.render_pass = renderer->getOffscreenRenderPass(); + framebuffer_create_info.render_pass = renderer->offscreenRenderPass; auto offscreen_framebuffer = gfx->create_framebuffer(framebuffer_create_info); @@ -993,7 +1002,7 @@ GFXTexture* CommonEditor::generate_common_preview(Scene& scene, const Vector3 ca GFXRenderPassBeginInfo begin_info = {}; begin_info.framebuffer = offscreen_framebuffer; - begin_info.render_pass = renderer->getOffscreenRenderPass(); + begin_info.render_pass = renderer->offscreenRenderPass; begin_info.render_area.extent = {thumbnail_resolution, thumbnail_resolution}; command_buffer->set_render_pass(begin_info); diff --git a/tools/common/src/debugpass.cpp b/tools/common/src/debugpass.cpp index 9c4b388..7605959 100755 --- a/tools/common/src/debugpass.cpp +++ b/tools/common/src/debugpass.cpp @@ -42,7 +42,7 @@ void DebugPass::initialize() { {1, GFXBindingType::PushConstant} }; - createInfo.render_pass = engine->get_renderer()->getOffscreenRenderPass(); + createInfo.render_pass = engine->get_renderer()->offscreenRenderPass; createInfo.rasterization.polygon_type = GFXPolygonType::Line; primitive_pipeline = engine->get_gfx()->create_graphics_pipeline(createInfo); @@ -159,7 +159,7 @@ void DebugPass::initialize() { pipelineInfo.blending.enable_blending = true; - pipelineInfo.render_pass = engine->get_renderer()->getOffscreenRenderPass(); + pipelineInfo.render_pass = engine->get_renderer()->offscreenRenderPass; billboard_pipeline = engine->get_gfx()->create_graphics_pipeline(pipelineInfo); diff --git a/tools/editor/include/prismeditor.hpp b/tools/editor/include/prismeditor.hpp index 595e17f..1aa10b9 100755 --- a/tools/editor/include/prismeditor.hpp +++ b/tools/editor/include/prismeditor.hpp @@ -10,10 +10,7 @@ class Scene; class Editor { public: std::string path; - - std::unique_ptr renderer; - DebugPass* debug_pass = nullptr; - + bool has_been_docked = false; bool modified = false; bool wants_to_close = false; diff --git a/tools/editor/src/materialeditor.cpp b/tools/editor/src/materialeditor.cpp index 64c9f84..41e04b3 100755 --- a/tools/editor/src/materialeditor.cpp +++ b/tools/editor/src/materialeditor.cpp @@ -184,7 +184,7 @@ void MaterialEditor::draw(CommonEditor* editor) { if(scene != nullptr) { ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); if(begin("Viewport")) - editor->drawViewport(*renderer); + editor->drawViewport(); ImGui::End(); diff --git a/tools/editor/src/prefabeditor.cpp b/tools/editor/src/prefabeditor.cpp index aef1aa9..6559211 100755 --- a/tools/editor/src/prefabeditor.cpp +++ b/tools/editor/src/prefabeditor.cpp @@ -92,7 +92,7 @@ void PrefabEditor::draw(CommonEditor* editor) { ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); if(begin("Viewport")) - editor->drawViewport(*renderer); + editor->drawViewport(); ImGui::End(); diff --git a/tools/editor/src/prismeditor.cpp b/tools/editor/src/prismeditor.cpp index a03120c..e26e08f 100755 --- a/tools/editor/src/prismeditor.cpp +++ b/tools/editor/src/prismeditor.cpp @@ -122,10 +122,7 @@ struct OpenAssetRequest { std::vector open_requests; void PrismEditor::setup_editor(Editor* editor) { - editor->renderer = std::make_unique(engine->get_gfx(), false); - editor->renderer->viewport_mode = true; - editor->debug_pass = editor->renderer->addPass(); - editor->renderer->resize_viewport({static_cast(viewport_width), static_cast(viewport_height)}); + } void PrismEditor::open_asset(const file::Path path) { @@ -181,7 +178,7 @@ void PrismEditor::open_asset(const file::Path path) { void PrismEditor::renderEditor(GFXCommandBuffer* command_buffer) { for (auto& editor : editors) { - editor->renderer->render(command_buffer, editor->get_scene(), -1); + //editor->renderer->render(command_buffer, editor->get_scene(), -1); } } @@ -317,10 +314,10 @@ void PrismEditor::drawUI() { ImGui::DockSpace(editor_dockspace, ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_None); - if(should_draw && editor->renderer != nullptr) { - debugPass = editor->debug_pass; + if(should_draw) { + /*debugPass = editor->debug_pass; if(debugPass != nullptr) - debugPass->selected_object = selected_object; + debugPass->selected_object = selected_object;*/ engine->set_current_scene(editor->get_scene()); set_undo_stack(&editor->undo_stack); diff --git a/tools/editor/src/sceneeditor.cpp b/tools/editor/src/sceneeditor.cpp index a6f0895..f8c76c5 100755 --- a/tools/editor/src/sceneeditor.cpp +++ b/tools/editor/src/sceneeditor.cpp @@ -156,7 +156,7 @@ void SceneEditor::draw(CommonEditor* editor) { if(showViewport) { ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); if(begin("Viewport", &showViewport)) - editor->drawViewport(*renderer); + editor->drawViewport(); ImGui::PopStyleVar();