diff --git a/src/base/film.h b/src/base/film.h index c6e0b999..ad26f158 100644 --- a/src/base/film.h +++ b/src/base/film.h @@ -52,6 +52,7 @@ class Film : public SceneNode { [[nodiscard]] virtual luisa::unique_ptr build( Pipeline &pipeline, CommandBuffer &command_buffer) const noexcept = 0; [[nodiscard]] virtual float clamp() const noexcept { return 1024.0f; } + [[nodiscard]] virtual bool is_display() const noexcept { return false; } }; }// namespace luisa::render diff --git a/src/base/integrator.cpp b/src/base/integrator.cpp index 1df4262e..3b54c9de 100644 --- a/src/base/integrator.cpp +++ b/src/base/integrator.cpp @@ -38,13 +38,15 @@ void ProgressiveIntegrator::Instance::render(Stream &stream) noexcept { auto resolution = camera->film()->node()->resolution(); auto pixel_count = resolution.x * resolution.y; camera->film()->prepare(command_buffer); - _render_one_camera(command_buffer, camera); - luisa::vector pixels(pixel_count); - camera->film()->download(command_buffer, pixels.data()); - command_buffer << compute::synchronize(); + { + _render_one_camera(command_buffer, camera); + luisa::vector pixels(pixel_count); + camera->film()->download(command_buffer, pixels.data()); + command_buffer << compute::synchronize(); + auto film_path = camera->node()->file(); + save_image(film_path, reinterpret_cast(pixels.data()), resolution); + } camera->film()->release(); - auto film_path = camera->node()->file(); - save_image(film_path, reinterpret_cast(pixels.data()), resolution); } } diff --git a/src/films/display.cpp b/src/films/display.cpp index cc5c3aa9..e098a681 100644 --- a/src/films/display.cpp +++ b/src/films/display.cpp @@ -52,8 +52,7 @@ class Display final : public Film { _tone_mapping{[desc] { auto tm = desc->property_string_or_default( "tone_mapping", lazy_construct([desc]() noexcept { - return desc->property_string_or_default( - "tonemapping", "none"); + return desc->property_string_or_default("tonemapping", "AgX"); })); for (auto &c : tm) { c = static_cast(std::tolower(c)); } if (tm == "uncharted2") { return ToneMapping::UNCHARTED2; } @@ -104,6 +103,7 @@ class Display final : public Film { [[nodiscard]] auto back_buffers() const noexcept { return _back_buffers; } [[nodiscard]] float3 exposure() const noexcept override { return make_float3(_exposure); } [[nodiscard]] auto tone_mapping() const noexcept { return _tone_mapping; } + [[nodiscard]] bool is_display() const noexcept override { return true; } [[nodiscard]] luisa::unique_ptr build( Pipeline &pipeline, CommandBuffer &command_buffer) const noexcept override; @@ -129,6 +129,7 @@ class DisplayInstance final : public Film::Instance { mutable int _tone_mapping{}; mutable int _background_fit{}; mutable bool _link_rgb_exposure{true}; + bool _rendering_done{}; private: [[nodiscard]] static auto _tone_mapping_uncharted2(Expr color) noexcept { @@ -284,6 +285,7 @@ class DisplayInstance final : public Film::Instance { void prepare(CommandBuffer &command_buffer) noexcept override { _base->prepare(command_buffer); + _rendering_done = false; auto &&device = pipeline().device(); auto size = node()->resolution(); if (!_window) { @@ -339,6 +341,12 @@ class DisplayInstance final : public Film::Instance { } void release() noexcept override { + _rendering_done = true; + CommandBuffer command_buffer{_stream}; + while (!_window->should_close()) { + this->show(command_buffer); + } + command_buffer << synchronize(); _window = nullptr; _framebuffer = {}; _base->release(); @@ -427,7 +435,7 @@ class DisplayInstance final : public Film::Instance { if (auto current_time = _clock.toc(); current_time - _last_frame_time >= interval) { _last_frame_time = current_time; - if (_window->should_close()) { + if (!_rendering_done && _window->should_close()) { command_buffer << synchronize(); exit(0);// FIXME: exit gracefully }