Commit 68f791f1 authored by Florian Oetke's avatar Florian Oetke
Browse files

changing resolution during runtime

parent 54beeb67
......@@ -63,15 +63,16 @@ namespace mirrage {
engine.assets(),
engine.input(),
_meta_system.renderer().find_pass<gui::Gui_renderer>())
, _performance_log(util::nothing) {
, _performance_log(util::nothing)
, _window_width(engine.window().width())
, _window_height(engine.window().height())
, _window_fullscreen(engine.window().fullscreen() != graphic::Fullscreen::no) {
_camera = _meta_system.entities().emplace("camera");
// TODO: check if model is available
auto cornell = _meta_system.entities().emplace("cornell");
cornell.get<Transform_comp>().process([&](auto& transform) { transform.position({1000, 0, 0}); });
// TODO: check if model is available
_meta_system.entities().emplace("sponza");
_sun = _meta_system.entities().emplace("sun");
......@@ -94,7 +95,7 @@ namespace mirrage {
[&](auto& transform) {
auto& cam = _camera.get<Transform_comp>().get_or_throw();
transform.position(cam.position() + cam.direction());
});
});
break;
case "d_disect"_strid: {
......@@ -109,28 +110,11 @@ namespace mirrage {
auto cam = _camera.get<Transform_comp>().get_or_throw().position();
INFO(
"Setup: \n"
<< " Camera position: "
<< cam.x
<< "/"
<< cam.y
<< "/"
<< cam.z
<< "\n"
<< " Camera orientation: "
<< _cam_yaw
<< "/"
<< _cam_pitch
<< "\n"
<< " Sun orientation: "
<< _sun_elevation
<< "/"
<< _sun_azimuth
<< "\n"
<< " Sun color: "
<< _sun_color_temperature
<< "\n"
<< " Disected: "
<< _meta_system.renderer().settings().debug_disect);
<< " Camera position: " << cam.x << "/" << cam.y << "/" << cam.z << "\n"
<< " Camera orientation: " << _cam_yaw << "/" << _cam_pitch << "\n"
<< " Sun orientation: " << _sun_elevation << "/" << _sun_azimuth << "\n"
<< " Sun color: " << _sun_color_temperature << "\n"
<< " Disected: " << _meta_system.renderer().settings().debug_disect);
break;
}
......@@ -151,7 +135,7 @@ namespace mirrage {
.process([&](auto&& rec) {
_selected_preset = 0;
_meta_system.nims().play_looped(rec);
});
});
break;
case "toggle_ui"_strid: _show_ui = !_show_ui; break;
......@@ -333,7 +317,7 @@ namespace mirrage {
if(nk_begin_titled(ctx,
"debug_controls",
"Debug Controls",
_gui.centered_left(250, 570),
_gui.centered_left(250, 640),
NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_TITLE | NK_WINDOW_MINIMIZABLE)) {
nk_layout_row_dynamic(ctx, 20, 2);
......@@ -381,27 +365,27 @@ namespace mirrage {
_update_sun_position();
_sun.get<renderer::Directional_light_comp>().process([&](
renderer::Directional_light_comp& light) {
auto new_size =
nk_propertyf(ctx, "Size", 0.5f, light.source_radius() / 1_m, 20.f, 0.1f, 0.01f);
light.source_radius(new_size * 1_m);
auto new_temp =
nk_propertyf(ctx, "Color", 500.f, _sun_color_temperature, 20000.f, 500.f, 50.f);
if(new_temp != _sun_color_temperature) {
light.temperature(_sun_color_temperature = new_temp);
_set_preset(0);
}
auto color = util::Rgba{light.color(), light.intensity() / 200.f};
if(gui::color_picker(ctx, color, 210.f)) {
light.color({color.r, color.g, color.b});
light.intensity(color.a * 200.f);
_set_preset(0);
}
});
_sun.get<renderer::Directional_light_comp>().process(
[&](renderer::Directional_light_comp& light) {
auto new_size = nk_propertyf(
ctx, "Size", 0.5f, light.source_radius() / 1_m, 20.f, 0.1f, 0.01f);
light.source_radius(new_size * 1_m);
auto new_temp = nk_propertyf(
ctx, "Color", 500.f, _sun_color_temperature, 20000.f, 500.f, 50.f);
if(new_temp != _sun_color_temperature) {
light.temperature(_sun_color_temperature = new_temp);
_set_preset(0);
}
auto color = util::Rgba{light.color(), light.intensity() / 200.f};
if(gui::color_picker(ctx, color, 210.f)) {
light.color({color.r, color.g, color.b});
light.intensity(color.a * 200.f);
_set_preset(0);
}
});
}
......@@ -410,6 +394,13 @@ namespace mirrage {
auto renderer_settings = _meta_system.renderer().settings();
auto bool_nk_wrapper = 0;
nk_property_int(ctx, "Window With", 640, &_window_width, 7680, 1, 1);
nk_property_int(ctx, "Window Height", 360, &_window_height, 4320, 1, 1);
bool_nk_wrapper = _window_fullscreen ? 1 : 0;
nk_checkbox_label(ctx, "Fullscreen", &bool_nk_wrapper);
_window_fullscreen = bool_nk_wrapper == 1;
nk_layout_row_dynamic(ctx, 20, 1);
nk_property_int(ctx, "Debug Layer", -1, &renderer_settings.debug_gi_layer, 5, 1, 1);
......@@ -451,6 +442,13 @@ namespace mirrage {
nk_layout_row_dynamic(ctx, 20, 1);
if(nk_button_label(ctx, "Apply")) {
if(_window_width != _engine.window().width() || _window_height != _engine.window().height()
|| _window_fullscreen != (_engine.window().fullscreen() != graphic::Fullscreen::no)) {
_engine.window().dimensions(_window_width,
_window_height,
_window_fullscreen ? graphic::Fullscreen::yes_borderless
: graphic::Fullscreen::no);
}
_meta_system.renderer().settings(renderer_settings, true);
} else {
_meta_system.renderer().settings(renderer_settings, false);
......@@ -502,7 +500,7 @@ namespace mirrage {
return gsl::narrow<int>(std::distance(container.begin(), top_entry));
}
}
} // namespace
void Test_screen::_draw_profiler_window() {
auto ctx = _gui.ctx();
if(nk_begin_titled(ctx,
......@@ -533,8 +531,8 @@ namespace mirrage {
nk_layout_row(ctx, NK_DYNAMIC, 10, rows.size(), rows.data());
auto print_entry = [&](
auto&& printer, const Profiler_result& result, int depth = 0, int rank = -1) -> void {
auto print_entry =
[&](auto&& printer, const Profiler_result& result, int depth = 0, int rank = -1) -> void {
auto color = [&] {
switch(rank) {
......@@ -574,4 +572,4 @@ namespace mirrage {
transform.position(transform.direction() * -60.f);
});
}
}
} // namespace mirrage
......@@ -67,6 +67,10 @@ namespace mirrage {
util::Time _performance_log_delay_left{1};
bool _preformance_log_first_row = true;
int _window_width;
int _window_height;
bool _window_fullscreen;
void _set_preset(int);
void _update_sun_position();
......
......@@ -140,6 +140,10 @@ namespace mirrage {
auto delta_time = std::max(0.f, static_cast<float>(_current_time - _last_time));
auto delta_time_smoothed = smooth(std::min(delta_time, 1.f / 1));
if(_graphics_main_window) {
_input_manager->viewport(_graphics_main_window->viewport());
}
_bus.update();
_input_manager->update(delta_time * second);
......
......@@ -5,6 +5,7 @@
#include <mirrage/graphic/settings.hpp>
#include <mirrage/graphic/transfer_manager.hpp>
#include <mirrage/graphic/vk_wrapper.hpp>
#include <mirrage/graphic/window.hpp>
#include <mirrage/asset/aid.hpp>
#include <mirrage/utils/purgatory.hpp>
......@@ -20,15 +21,22 @@
namespace mirrage::graphic {
class Swapchain {
class Swapchain : public Window_modification_handler {
public:
Swapchain() = default;
Swapchain(const vk::Device& dev, Window&, vk::SwapchainCreateInfoKHR);
Swapchain(const vk::Device& dev, vk::PhysicalDevice, Window&, vk::SwapchainCreateInfoKHR);
Swapchain(Swapchain&&) = default;
Swapchain& operator=(Swapchain&&) = default;
~Swapchain() = default;
auto get_images() const -> auto& { return _image_views; }
auto acquireNextImage(vk::Semaphore, vk::Fence) const -> std::size_t;
void present(vk::Queue&, std::size_t img_index, vk::Semaphore) const;
bool present(vk::Queue&, std::size_t img_index, vk::Semaphore);
void recreate();
void on_window_modified(Window&) override;
auto image_width() const noexcept { return _image_width; }
auto image_height() const noexcept { return _image_height; }
......@@ -36,13 +44,18 @@ namespace mirrage::graphic {
private:
const vk::Device& _device;
vk::PhysicalDevice _gpu;
Window& _window;
vk::SwapchainCreateInfoKHR _info;
vk::UniqueSwapchainKHR _swapchain;
std::vector<vk::Image> _images;
std::vector<vk::UniqueImageView> _image_views;
int _image_width;
int _image_height;
vk::Format _image_format;
bool _recreate_pending = false;
void _create_image_views();
};
enum class Format_usage { buffer, image_linear, image_optimal };
......@@ -147,7 +160,7 @@ namespace mirrage::graphic {
void backup_caches();
auto context() -> auto& { return parent(); }
auto context() -> auto& { return util::Registered<Device, Context>::parent(); }
void wait_idle() {
_device->waitIdle();
......
......@@ -28,7 +28,23 @@ namespace mirrage::asset {
namespace mirrage::graphic {
class Window : public util::Registered<Window, Context> {
class Window;
class Window_modification_handler : public util::Registered<Window_modification_handler, Window> {
public:
Window_modification_handler(Window& w) : util::Registered<Window_modification_handler, Window>(w) {}
Window_modification_handler(const Window_modification_handler&) = default;
Window_modification_handler(Window_modification_handler&&) = default;
virtual ~Window_modification_handler() = default;
Window_modification_handler& operator=(const Window_modification_handler&) = default;
Window_modification_handler& operator=(Window_modification_handler&&) = default;
virtual void on_window_modified(Window&) = 0;
};
class Window : public util::Registered<Window, Context>,
public util::Registration<Window, Window_modification_handler> {
public:
Window(Context& context,
std::string name,
......@@ -52,6 +68,7 @@ namespace mirrage::graphic {
auto width() const noexcept { return _width; }
auto height() const noexcept { return _height; }
auto fullscreen() const noexcept { return _fullscreen; }
auto viewport() const noexcept { return glm::vec4(0.f, 0.f, width(), height()); }
private:
......
......@@ -74,36 +74,81 @@ namespace mirrage::graphic {
}
}
Swapchain::Swapchain(const vk::Device& dev, Window& window, vk::SwapchainCreateInfoKHR info)
: _device(dev)
Swapchain::Swapchain(const vk::Device& dev,
vk::PhysicalDevice gpu,
Window& window,
vk::SwapchainCreateInfoKHR info)
: Window_modification_handler(window)
, _device(dev)
, _gpu(gpu)
, _window(window)
, _info(info)
, _swapchain(dev.createSwapchainKHRUnique(info))
, _images(dev.getSwapchainImagesKHR(*_swapchain))
, _image_width(info.imageExtent.width)
, _image_height(info.imageExtent.height)
, _image_format(info.imageFormat) {
DEBUG("Created swapchain with " << _images.size() << " images (min=" << info.minImageCount << ")");
_create_image_views();
}
void Swapchain::_create_image_views() {
DEBUG("Created swapchain with " << _images.size() << " images (min=" << _info.minImageCount << ")");
_image_views.clear();
_image_views.reserve(_images.size());
for(auto& image : _images) {
auto ivc = vk::ImageViewCreateInfo{};
ivc.setImage(image);
ivc.setViewType(vk::ImageViewType::e2D);
ivc.setFormat(info.imageFormat);
ivc.setFormat(_info.imageFormat);
ivc.setSubresourceRange(vk::ImageSubresourceRange{vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1});
_image_views.emplace_back(dev.createImageViewUnique(ivc));
_image_views.emplace_back(_device.createImageViewUnique(ivc));
}
}
auto Swapchain::acquireNextImage(vk::Semaphore s, vk::Fence f) const -> std::size_t {
return _device.acquireNextImageKHR(*_swapchain, std::numeric_limits<std::uint64_t>::max(), s, f).value;
}
void Swapchain::present(vk::Queue& q, std::size_t img_index, vk::Semaphore s) const {
bool Swapchain::present(vk::Queue& q, std::size_t img_index, vk::Semaphore s) {
auto img_index_vk = gsl::narrow<uint32_t>(img_index);
q.presentKHR(vk::PresentInfoKHR{s ? 1u : 0u, &s, 1, &*_swapchain, &img_index_vk});
auto info = vk::PresentInfoKHR{s ? 1u : 0u, &s, 1, &*_swapchain, &img_index_vk};
auto result = vkQueuePresentKHR(VkQueue(q), reinterpret_cast<VkPresentInfoKHR*>(&info));
_window.on_present();
if(result != VK_SUCCESS || _recreate_pending) {
_recreate_pending = false;
_device.waitIdle();
auto capabilities = _gpu.getSurfaceCapabilitiesKHR(_window.surface());
DEBUG("Extends: " << capabilities.currentExtent.width << ", "
<< capabilities.currentExtent.height);
_image_width = _window.width();
_image_height = _window.height();
_info.oldSwapchain = *_swapchain;
_info.imageExtent.width = _image_width;
_info.imageExtent.height = _image_height;
_swapchain = _device.createSwapchainKHRUnique(_info);
_images = _device.getSwapchainImagesKHR(*_swapchain);
_create_image_views();
INFO("Swapchain recreated");
return true;
}
return false;
}
void Swapchain::recreate() { _recreate_pending = true; }
void Swapchain::on_window_modified(Window& window) { recreate(); }
Device::Device(Context& context,
asset::Asset_manager& assets,
......@@ -186,7 +231,7 @@ namespace mirrage::graphic {
for(auto& sc_info : swapchains) {
_swapchains.emplace(
sc_info.first,
Swapchain{*_device, *std::get<0>(sc_info.second), std::get<1>(sc_info.second)});
Swapchain{*_device, _gpu, *std::get<0>(sc_info.second), std::get<1>(sc_info.second)});
}
}
......
......@@ -137,10 +137,20 @@ namespace mirrage::graphic {
if(_fullscreen != fullscreen) {
_fullscreen = fullscreen;
auto fs_type =
fullscreen == Fullscreen::yes ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP;
const auto fs_type = [&]() -> Uint32 {
switch(fullscreen) {
case Fullscreen::no: return 0;
case Fullscreen::yes: return SDL_WINDOW_FULLSCREEN;
case Fullscreen::yes_borderless: return SDL_WINDOW_FULLSCREEN_DESKTOP;
}
}();
SDL_SetWindowFullscreen(_window.get(), fs_type);
SDL_SetWindowDisplayMode(_window.get(), &closest);
if(fullscreen != Fullscreen::no) {
SDL_SetWindowDisplayMode(_window.get(), &closest);
} else {
SDL_SetWindowSize(_window.get(), width, height);
}
}
SDL_GetWindowSize(_window.get(), &width, &height);
......@@ -149,7 +159,10 @@ namespace mirrage::graphic {
sdl_error_check();
// TODO: report changed size to renderer => change viewport
// report changed size to renderer => change viewport
for(auto& listener : util::Registration<Window, Window_modification_handler>::children()) {
listener->on_window_modified(*this);
}
return true;
}
......
......@@ -99,6 +99,8 @@ namespace mirrage::gui {
auto ctx() -> nk_context*;
auto renderer() noexcept -> auto& { return _renderer; }
void viewport(glm::vec4 new_viewport);
auto centered(int width, int height) -> struct nk_rect;
auto centered_left(int width, int height) -> struct nk_rect;
auto centered_right(int width, int height) -> struct nk_rect;
......
......@@ -59,7 +59,7 @@ namespace mirrage::gui {
public:
Gui_event_filter(input::Input_manager& input_mgr,
nk_context* ctx,
glm::vec4 viewport,
const glm::vec4& viewport,
const glm::mat4& ui_matrix)
: Sdl_event_filter(input_mgr)
, _input_mgr(input_mgr)
......@@ -189,8 +189,8 @@ namespace mirrage::gui {
private:
input::Input_manager& _input_mgr;
nk_context* _ctx;
glm::vec4 _viewport;
glm::mat4 _ui_matrix;
const glm::vec4& _viewport;
const glm::mat4& _ui_matrix;
bool _grab_clicks = false;
bool _grab_inputs = false;
};
......@@ -390,13 +390,12 @@ namespace mirrage::gui {
asset::Asset_manager& assets,
input::Input_manager& input,
Gui_renderer& renderer)
: viewport(viewport)
, screen_size(normalize_screen_size(viewport.z - viewport.x, viewport.w - viewport.y, 720))
, ui_matrix(build_ui_mat(screen_size))
, renderer(renderer)
: renderer(renderer)
, atlas(assets)
, atlas_tex(renderer.load_texture(atlas.width, atlas.height, 4, atlas.data))
, input_filter(input, &ctx.ctx, viewport, ui_matrix) {
, input_filter(input, &ctx.ctx, this->viewport, ui_matrix) {
change_viewport(viewport);
atlas.post_init(ctx.ctx, this->renderer.null_tex, *atlas_tex);
......@@ -409,6 +408,14 @@ namespace mirrage::gui {
ctx.ctx.style.window.menu_border_color = nk_rgb(0, 0, 0);
}
~PImpl() {}
void change_viewport(glm::vec4 new_viewport) {
viewport = new_viewport;
screen_size = normalize_screen_size(static_cast<int>(viewport.z - viewport.x),
static_cast<int>(viewport.w - viewport.y),
720);
ui_matrix = build_ui_mat(screen_size);
}
};
Gui::Gui(glm::vec4 viewport,
......@@ -440,6 +447,11 @@ namespace mirrage::gui {
}
}
void Gui::viewport(glm::vec4 new_viewport) {
_viewport = new_viewport;
_impl->change_viewport(new_viewport);
}
void Gui_renderer::draw_gui() {
if(_gui) {
_gui->draw();
......@@ -456,6 +468,8 @@ namespace mirrage::gui {
return;
}
viewport(_input.viewport());
_impl->renderer.draw(_impl->ctx.ctx, _impl->viewport, _impl->screen_size, _impl->ui_matrix);
}
......
......@@ -61,6 +61,8 @@ namespace mirrage::input {
void screen_to_world_coords(std::function<glm::vec2(glm::vec2)> func) {
_screen_to_world_coords = func;
}
auto viewport() const noexcept { return _viewport; }
void viewport(glm::vec4 v) { _viewport = v; }
void window(SDL_Window* w) { _sdl_window = w; }
......
......@@ -138,7 +138,7 @@ namespace mirrage::renderer {
Pass_factories _pass_factories;
graphic::Window& _window;
graphic::Device_ptr _device;
const graphic::Swapchain& _swapchain;
graphic::Swapchain& _swapchain;
std::uint32_t _queue_family;
vk::Queue _queue;
vk::UniqueSemaphore _image_acquired;
......
......@@ -299,9 +299,11 @@ namespace mirrage::renderer {
_queued_commands.clear();
// present
_swapchain.present(_queue, _aquired_swapchain_image.get_or_throw(), *_image_presented);
if(_swapchain.present(_queue, _aquired_swapchain_image.get_or_throw(), *_image_presented)) {
_recreation_pending = true;
}
_aquired_swapchain_image = util::nothing;
_window.on_present();
}
auto Deferred_renderer_factory::_rank_device(vk::PhysicalDevice gpu, util::maybe<std::uint32_t> gqueue)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment