From ed0b81dcbdd718e55a9d09b6da54950c664be9c3 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sun, 23 Oct 2022 18:14:05 +0200 Subject: a --- main/debug.cpp | 18 ++----- main/floormat-app.hpp | 2 +- main/floormat-main-impl.cpp | 119 ++++++++++++++++++++++++++++++++++++++------ main/floormat-main-impl.hpp | 23 ++++++--- main/floormat-main.hpp | 5 +- 5 files changed, 131 insertions(+), 36 deletions(-) (limited to 'main') diff --git a/main/debug.cpp b/main/debug.cpp index 4ce4a3b0..7e012b9d 100644 --- a/main/debug.cpp +++ b/main/debug.cpp @@ -1,18 +1,12 @@ -#include "main.hpp" +#include "floormat-main-impl.hpp" #include -#include namespace floormat { -using Feature = GL::Renderer::Feature; -using Source = GL::DebugOutput::Source; -using Type = GL::DebugOutput::Type; using Severity = GL::DebugOutput::Severity; -using GL::Renderer; -using GL::DebugOutput; // NOLINTNEXTLINE(readability-convert-member-functions-to-static) -void floormat::debug_callback(GL::DebugOutput::Source src, GL::DebugOutput::Type type, UnsignedInt id, +void main_impl::debug_callback(GL::DebugOutput::Source src, GL::DebugOutput::Type type, UnsignedInt id, Severity severity, const std::string& str) const { static thread_local auto clock = std::chrono::steady_clock{}; @@ -58,13 +52,13 @@ void floormat::debug_callback(GL::DebugOutput::Source src, GL::DebugOutput::Type std::fputs("", stdout); // put breakpoint here } -void floormat::_debug_callback(GL::DebugOutput::Source src, GL::DebugOutput::Type type, UnsignedInt id, +void main_impl::_debug_callback(GL::DebugOutput::Source src, GL::DebugOutput::Type type, UnsignedInt id, GL::DebugOutput::Severity severity, const std::string& str, const void* self) { - static_cast(self)->debug_callback(src, type, id, severity, str); + static_cast(self)->debug_callback(src, type, id, severity, str); } -void* floormat::register_debug_callback() +void main_impl::register_debug_callback() noexcept { GL::DebugOutput::setCallback(_debug_callback, this); @@ -72,8 +66,6 @@ void* floormat::register_debug_callback() /* Disable rather spammy "Buffer detailed info" debug messages on NVidia drivers */ GL::DebugOutput::setEnabled(GL::DebugOutput::Source::Api, GL::DebugOutput::Type::Other, {131185}, false); #endif - - return nullptr; } } // namespace floormat diff --git a/main/floormat-app.hpp b/main/floormat-app.hpp index f5e57c6e..31cffaed 100644 --- a/main/floormat-app.hpp +++ b/main/floormat-app.hpp @@ -20,7 +20,7 @@ struct floormat_app fm_DECLARE_DELETED_COPY_ASSIGNMENT(floormat_app); fm_DECLARE_DEPRECATED_MOVE_ASSIGNMENT(floormat_app); - virtual void update(double dt) = 0; + virtual void update(float dt) = 0; virtual void draw_msaa(); virtual void draw() = 0; diff --git a/main/floormat-main-impl.cpp b/main/floormat-main-impl.cpp index 56c19882..85fd5cb9 100644 --- a/main/floormat-main-impl.cpp +++ b/main/floormat-main-impl.cpp @@ -3,11 +3,17 @@ #include "floormat-app.hpp" #include "compat/assert.hpp" #include "compat/fpu.hpp" +#include "src/chunk.hpp" +#include "src/world.hpp" +#include "src/camera-offset.hpp" + +//#define FM_SKIP_MSAA namespace floormat { floormat_main::floormat_main() noexcept = default; floormat_main::~floormat_main() noexcept = default; +main_impl::~main_impl() noexcept = default; static const char* const fm_fake_argv[] = { "floormat", nullptr }; @@ -28,7 +34,15 @@ auto main_impl::make_window_flags(const fm_options& s) -> Configuration::WindowF return flags; } -void main_impl::recalc_viewport(Vector2i size) +auto main_impl::make_conf(const fm_options& s) -> Configuration +{ + return Configuration{} + .setTitle(s.title) + .setSize(s.resolution) + .setWindowFlags(make_window_flags(s)); +} + +void main_impl::recalc_viewport(Vector2i size) noexcept { GL::defaultFramebuffer.setViewport({{}, size }); #ifdef FM_MSAA @@ -40,23 +54,15 @@ void main_impl::recalc_viewport(Vector2i size) #endif _shader.set_scale(Vector2(size)); app.on_viewport_event(size); - setMinimalLoopPeriod(5); } -auto main_impl::make_conf(const fm_options& s) -> Configuration -{ - return Configuration{} - .setTitle(s.title) - .setSize(s.resolution) - .setWindowFlags(make_window_flags(s)); -} - -main_impl::main_impl(floormat_app& app, const fm_options& s) : +// NOLINTNEXTLINE(performance-unnecessary-value-param) +main_impl::main_impl(floormat_app& app, fm_options s) noexcept : Platform::Sdl2Application{Arguments{fake_argc, fm_fake_argv}, make_conf(s), make_gl_conf(s)}, - app{app}, s{s} + app{app}, s{std::move(s)} { - switch (s.vsync) + switch (s.vsync) // NOLINT(bugprone-use-after-move) { case fm_tristate::on: (void)setSwapInterval(1); @@ -75,7 +81,60 @@ main_impl::main_impl(floormat_app& app, const fm_options& s) : timeline.start(); } -main_impl::~main_impl() = default; +global_coords main_impl::pixel_to_tile(Vector2d position) const noexcept +{ + constexpr Vector2d pixel_size{dTILE_SIZE[0], dTILE_SIZE[1]}; + constexpr Vector2d half{.5, .5}; + const Vector2d px = position - Vector2d{windowSize()}*.5 - _shader.camera_offset()*.5; + const Vector2d vec = tile_shader::unproject(px) / pixel_size + half; + const auto x = (std::int32_t)std::floor(vec[0]), y = (std::int32_t)std::floor(vec[1]); + return { x, y }; +} + +auto main_impl::get_draw_bounds() const noexcept -> draw_bounds +{ + + using limits = std::numeric_limits; + auto x0 = limits::max(), x1 = limits::min(), y0 = limits::max(), y1 = limits::min(); + + for (const auto win = Vector2d(windowSize()); + auto p : {pixel_to_tile(Vector2d{0, 0}).chunk(), + pixel_to_tile(Vector2d{win[0]-1, 0}).chunk(), + pixel_to_tile(Vector2d{0, win[1]-1}).chunk(), + pixel_to_tile(Vector2d{win[0]-1, win[1]-1}).chunk()}) + { + x0 = std::min(x0, p.x); + x1 = std::max(x1, p.x); + y0 = std::min(y0, p.y); + y1 = std::max(y1, p.y); + } + return {x0, x1, y0, y1}; +} + +void main_impl::draw_world() noexcept +{ + auto [minx, maxx, miny, maxy] = get_draw_bounds(); + + for (std::int16_t y = miny; y <= maxy; y++) + for (std::int16_t x = minx; x <= maxx; x++) + { +#if 0 + if (const chunk_coords c = {x, y}; !_world.contains(c)) + make_test_chunk(*_world[c]); +#endif + const chunk_coords c{x, y}; + const with_shifted_camera_offset o{_shader, c}; + _floor_mesh.draw(_shader, *_world[c]); + } + + for (std::int16_t y = miny; y <= maxy; y++) + for (std::int16_t x = minx; x <= maxx; x++) + { + const chunk_coords c{x, y}; + const with_shifted_camera_offset o{_shader, c}; + _wall_mesh.draw(_shader, *_world[c]); + } +} void main_impl::drawEvent() { @@ -87,15 +146,45 @@ void main_impl::drawEvent() _frame_time = _frame_time*(1-alpha) + alpha*dt; } else + { swapBuffers(); timeline.nextFrame(); + } - const auto dt = std::clamp((double)timeline.previousFrameDuration(), 1e-6, 1e-1); + const float dt = std::clamp(timeline.previousFrameDuration(), 1e-6f, 1e-1f); app.update(dt); _shader.set_tint({1, 1, 1, 1}); + + { + GL::defaultFramebuffer.clear(GL::FramebufferClear::Color); +#if defined FM_MSAA && !defined FM_SKIP_MSAA + _msaa_framebuffer.clear(GL::FramebufferClear::Color); + _msaa_framebuffer.bind(); +#endif + draw_world(); + app.draw_msaa(); +#if defined FM_MSAA && !defined FM_SKIP_MSAA + GL::defaultFramebuffer.bind(); + GL::Framebuffer::blit(_msaa_framebuffer, GL::defaultFramebuffer, {{}, windowSize()}, GL::FramebufferBlit::Color); +#endif + } + + app.draw(); + + swapBuffers(); + redraw(); + timeline.nextFrame(); } +void main_impl::quit(int status) +{ + Platform::Sdl2Application::exit(status); +} + +Vector2i main_impl::window_size() const noexcept { return windowSize(); } +tile_shader& shader() noexcept { return _shader; } + floormat_main* floormat_main::create(floormat_app& app, const fm_options& options) { auto* ret = new main_impl(app, options); diff --git a/main/floormat-main-impl.hpp b/main/floormat-main-impl.hpp index e0cb0747..8541d095 100644 --- a/main/floormat-main-impl.hpp +++ b/main/floormat-main-impl.hpp @@ -1,6 +1,9 @@ #pragma once #include "floormat.hpp" #include "floormat-main.hpp" +#include "src/world.hpp" +#include "draw/floor-mesh.hpp" +#include "draw/wall-mesh.hpp" #include "shaders/tile-shader.hpp" #include #include @@ -14,8 +17,8 @@ struct floormat_app; struct main_impl final : Platform::Sdl2Application, floormat_main { - main_impl(floormat_app& app, const fm_options& opts); - ~main_impl() override; + main_impl(floormat_app& app, fm_options opts) noexcept; + ~main_impl() noexcept override; void quit(int status) override; @@ -25,7 +28,8 @@ struct main_impl final : Platform::Sdl2Application, floormat_main struct world& world() noexcept override; SDL_Window* window() noexcept override; - float smoothed_dt() const noexcept override; + + global_coords pixel_to_tile(Vector2d position) const noexcept override; [[maybe_unused]] void viewportEvent(ViewportEvent& event) override; [[maybe_unused]] void mousePressEvent(MouseEvent& event) override; @@ -39,19 +43,26 @@ struct main_impl final : Platform::Sdl2Application, floormat_main void drawEvent() override; private: - float _frame_time = 0; floormat_app& app; - fm_options s; tile_shader _shader; + struct world _world{}; + floor_mesh _floor_mesh; + wall_mesh _wall_mesh; Magnum::Timeline timeline; + fm_options s; int fake_argc = 1; + struct draw_bounds final { std::int16_t minx, maxx, miny, maxy; }; + #ifdef FM_MSAA GL::Framebuffer _msaa_framebuffer{{{}, windowSize()}}; GL::Renderbuffer _msaa_renderbuffer{}; #endif - void recalc_viewport(Vector2i size); + void recalc_viewport(Vector2i size) noexcept; + void draw_world() noexcept; + + draw_bounds get_draw_bounds() const noexcept; void debug_callback(GL::DebugOutput::Source src, GL::DebugOutput::Type type, UnsignedInt id, GL::DebugOutput::Severity severity, const std::string& str) const; diff --git a/main/floormat-main.hpp b/main/floormat-main.hpp index 5f0635cc..7b984781 100644 --- a/main/floormat-main.hpp +++ b/main/floormat-main.hpp @@ -1,6 +1,7 @@ #pragma once #include "floormat.hpp" +#include "src/global-coords.hpp" #include struct SDL_Window; @@ -22,9 +23,11 @@ struct floormat_main virtual void quit(int status) = 0; virtual Magnum::Math::Vector2 window_size() const noexcept = 0; - virtual float smoothed_dt() const noexcept = 0; virtual tile_shader& shader() noexcept = 0; virtual void register_debug_callback() noexcept = 0; + constexpr float smoothed_dt() const noexcept { return _smoothed_dt; } + + virtual global_coords pixel_to_tile(Vector2d position) const noexcept = 0; virtual world& world() noexcept = 0; virtual SDL_Window* window() noexcept = 0; -- cgit v1.2.3