summaryrefslogtreecommitdiffhomepage
path: root/main
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2022-10-23 18:14:05 +0200
committerStanislaw Halik <sthalik@misaki.pl>2022-10-23 18:14:05 +0200
commited0b81dcbdd718e55a9d09b6da54950c664be9c3 (patch)
tree85af67a840737e176bc489193a06de9566401432 /main
parentcce1f768e7399b838a2b865511915bdd576dbbf4 (diff)
a
Diffstat (limited to 'main')
-rw-r--r--main/debug.cpp18
-rw-r--r--main/floormat-app.hpp2
-rw-r--r--main/floormat-main-impl.cpp119
-rw-r--r--main/floormat-main-impl.hpp23
-rw-r--r--main/floormat-main.hpp5
5 files changed, 131 insertions, 36 deletions
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 <chrono>
-#include <Magnum/GL/Renderer.h>
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<const floormat*>(self)->debug_callback(src, type, id, severity, str);
+ static_cast<const main_impl*>(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<std::int16_t>;
+ 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 <Corrade/Containers/String.h>
#include <Magnum/GL/RenderbufferFormat.h>
@@ -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 <Magnum/Math/Vector2.h>
struct SDL_Window;
@@ -22,9 +23,11 @@ struct floormat_main
virtual void quit(int status) = 0;
virtual Magnum::Math::Vector2<int> 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;