diff --git a/libs/gfx/include/psemek/gfx/renderer/deferred.hpp b/libs/gfx/include/psemek/gfx/renderer/deferred.hpp index 15bd4125..b267ac4b 100644 --- a/libs/gfx/include/psemek/gfx/renderer/deferred.hpp +++ b/libs/gfx/include/psemek/gfx/renderer/deferred.hpp @@ -19,6 +19,16 @@ namespace psemek::gfx deferred_renderer(); ~deferred_renderer(); + enum class position_mode + { + // Default position mode is float32 + // TODO: support fixed16 & fixed32 + float16, + float32, + }; + + void set_position_mode(position_mode mode); + struct material { std::optional color; diff --git a/libs/gfx/source/renderer/deferred.cpp b/libs/gfx/source/renderer/deferred.cpp index 70937183..3bb3424d 100644 --- a/libs/gfx/source/renderer/deferred.cpp +++ b/libs/gfx/source/renderer/deferred.cpp @@ -549,6 +549,9 @@ void main() struct deferred_renderer::impl { + deferred_renderer::position_mode position_mode = deferred_renderer::position_mode::float32; + bool position_mode_changed = true; + gfx::program g_buffer_pass_program{std::string(g_buffer_pass_common) + g_buffer_pass_vs, std::string(g_buffer_pass_common) + g_buffer_pass_fs}; gfx::program ambient_pass_program{fullscreen_vs, std::string(light_common) + ambient_pass_fs}; gfx::program directional_light_pass_program{screen_vs, std::string(light_common) + directional_light_pass_fs}; @@ -634,6 +637,12 @@ void main() deferred_renderer::~deferred_renderer() = default; + void deferred_renderer::set_position_mode(position_mode mode) + { + impl().position_mode = mode; + impl().position_mode_changed = true; + } + static std::uint32_t const O_UNIFORM_COLOR = 1 << 0; static std::uint32_t const O_TEXTURE_COLOR = 1 << 1; static std::uint32_t const O_TRANSPARENT = 1 << 2; @@ -690,13 +699,21 @@ void main() // Resize g-buffer if needed auto buffer_size = geom::cast(target.viewport.dimensions()); - if (!impl().g_buffer_size || *impl().g_buffer_size != buffer_size) + bool const buffer_size_changed = !impl().g_buffer_size || *impl().g_buffer_size != buffer_size; + if (buffer_size_changed || impl().position_mode_changed) { - impl().g_buffer_texture[0].load>(buffer_size); - impl().g_buffer_texture[1].load>(buffer_size); - impl().g_buffer_texture[2].load>(buffer_size); - impl().g_buffer_texture[3].load>(buffer_size); - impl().g_buffer_depth.load(buffer_size); + if (impl().position_mode == position_mode::float16) + impl().g_buffer_texture[0].load>(buffer_size); + else if (impl().position_mode == position_mode::float32) + impl().g_buffer_texture[0].load>(buffer_size); + + if (buffer_size_changed) + { + impl().g_buffer_texture[1].load>(buffer_size); + impl().g_buffer_texture[2].load>(buffer_size); + impl().g_buffer_texture[3].load>(buffer_size); + impl().g_buffer_depth.load(buffer_size); + } if (!impl().g_buffer_size) { @@ -710,6 +727,7 @@ void main() impl().g_framebuffer.assert_complete(); impl().g_buffer_size = buffer_size; + impl().position_mode_changed = false; } // Setup g-buffer @@ -1073,15 +1091,6 @@ void main() o.mesh->draw(); } } -/* - gfx::pixmap_float pixmap({impl().point_shadow_texture.width(), impl().point_shadow_texture.height()}); - impl().point_shadow_texture.pixels(1, gl::DEPTH_COMPONENT, gl::FLOAT, pixmap.data()); - - auto pixels = util::map([](float x){ return std::uint8_t(x * 255); }, pixmap); - - std::ofstream out{"/home/lisyarus/depth.pgm"}; - gfx::write_pgm(pixels, out); -//*/ } target.bind();