diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2022-11-29 22:15:27 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-11-29 22:32:46 +0100 |
commit | 9c5027215e1052adb0131362207b78ec89822985 (patch) | |
tree | ad928799caedab4fa497802e8981db9dc66fcc76 | |
parent | 2659fae8c838601282b9b90d5e0dc8b1da3f3f2b (diff) |
fix z value discontinuity on chunk boundaries
-rw-r--r-- | editor/camera.cpp | 4 | ||||
-rw-r--r-- | main/draw.cpp | 24 | ||||
-rw-r--r-- | main/main-impl.hpp | 2 | ||||
-rw-r--r-- | shaders/tile.cpp | 14 | ||||
-rw-r--r-- | shaders/tile.hpp | 9 | ||||
-rw-r--r-- | shaders/tile.vert | 4 | ||||
-rw-r--r-- | src/camera-offset.cpp | 14 | ||||
-rw-r--r-- | src/camera-offset.hpp | 6 |
8 files changed, 45 insertions, 32 deletions
diff --git a/editor/camera.cpp b/editor/camera.cpp index e22b20ba..d7fc8695 100644 --- a/editor/camera.cpp +++ b/editor/camera.cpp @@ -41,7 +41,7 @@ void app::do_camera(float dt, const key_set& cmds, int mods) camera_offset[0] = std::clamp(camera_offset[0], -max_camera_offset[0], max_camera_offset[0]); camera_offset[1] = std::clamp(camera_offset[1], -max_camera_offset[1], max_camera_offset[1]); - shader.set_camera_offset(camera_offset); + shader.set_camera_offset(camera_offset, shader.depth_offset()); update_cursor_tile(cursor.pixel); do_mouse_move(mods); @@ -52,7 +52,7 @@ void app::reset_camera_offset() { constexpr Vector3d size = TILE_MAX_DIM20d*dTILE_SIZE*-.5; constexpr auto projected = tile_shader::project(size); - M->shader().set_camera_offset(projected); + M->shader().set_camera_offset(projected, 0); update_cursor_tile(cursor.pixel); } diff --git a/main/draw.cpp b/main/draw.cpp index 3c3ba97b..cab331ff 100644 --- a/main/draw.cpp +++ b/main/draw.cpp @@ -24,11 +24,11 @@ void main_impl::recalc_viewport(Vector2i size) noexcept _screen.fb = GL::Framebuffer{{{}, size}}; _screen.color = GL::Renderbuffer{}; _screen.color.setStorage(GL::RenderbufferFormat::RGBA8, size); - _screen.depth = GL::Renderbuffer{}; - _screen.depth.setStorage(GL::RenderbufferFormat::DepthComponent32F, size); + _screen.depthstencil = GL::Renderbuffer{}; + _screen.depthstencil.setStorage(GL::RenderbufferFormat::Depth24Stencil8, size); _screen.fb.attachRenderbuffer(GL::Framebuffer::ColorAttachment{0}, _screen.color); - _screen.fb.attachRenderbuffer(GL::Framebuffer::BufferAttachment::Depth, _screen.depth); + _screen.fb.attachRenderbuffer(GL::Framebuffer::BufferAttachment::DepthStencil, _screen.depthstencil); update_window_state(); _shader.set_scale(Vector2{size}); @@ -92,20 +92,24 @@ void main_impl::draw_world() noexcept const chunk_coords pos{x, y}; if (!_world.contains(pos)) app.maybe_initialize_chunk(pos, _world[pos]); - const with_shifted_camera_offset o{_shader, pos}; + auto& c = _world[pos]; + if (c.empty()) + continue; + const with_shifted_camera_offset o{_shader, pos, {minx, miny}, {maxx, maxy}}; if (check_chunk_visible(_shader.camera_offset(), sz)) - _floor_mesh.draw(_shader, _world[pos]); + _floor_mesh.draw(_shader, c); } GL::Renderer::enable(GL::Renderer::Feature::DepthTest); - constexpr float clear_depth = -1 << 24; - _screen.fb.clearDepth(clear_depth); + _screen.fb.clearDepth(0); for (std::int16_t y = miny; y <= maxy; y++) for (std::int16_t x = minx; x <= maxx; x++) { const chunk_coords pos{x, y}; auto& c = _world[pos]; - const with_shifted_camera_offset o{_shader, pos}; + if (c.empty()) + continue; + const with_shifted_camera_offset o{_shader, pos, {minx, miny}, {maxx, maxy}}; if (check_chunk_visible(_shader.camera_offset(), sz)) _wall_mesh.draw(_shader, c); } @@ -122,7 +126,9 @@ void main_impl::draw_anim() noexcept { const chunk_coords pos{x, y}; auto& c = _world[pos]; - const with_shifted_camera_offset o{_shader, pos}; + if (c.empty()) + continue; + const with_shifted_camera_offset o{_shader, pos, {minx, miny}, {maxx, maxy}}; if (check_chunk_visible(_shader.camera_offset(), sz)) for (std::size_t i = 0; i < TILE_COUNT; i++) { diff --git a/main/main-impl.hpp b/main/main-impl.hpp index 85c61951..e923306f 100644 --- a/main/main-impl.hpp +++ b/main/main-impl.hpp @@ -81,7 +81,7 @@ private: struct { GL::Framebuffer fb{NoCreate}; - GL::Renderbuffer color{NoCreate}, depth{NoCreate}; + GL::Renderbuffer color{NoCreate}, depthstencil{NoCreate}; } _screen; Magnum::Timeline timeline; floor_mesh _floor_mesh; diff --git a/shaders/tile.cpp b/shaders/tile.cpp index ff08de2e..9df05f8e 100644 --- a/shaders/tile.cpp +++ b/shaders/tile.cpp @@ -31,7 +31,7 @@ tile_shader::tile_shader() set_scale({640, 480}); set_tint({1, 1, 1, 1}); - setUniform(OffsetUniform, Vector2{}); + setUniform(OffsetUniform, Vector3{}); } tile_shader::~tile_shader() = default; @@ -43,9 +43,10 @@ tile_shader& tile_shader::set_scale(const Vector2& scale) return *this; } -tile_shader& tile_shader::set_camera_offset(Vector2d camera_offset) +tile_shader& tile_shader::set_camera_offset(const Vector2d& camera_offset, float depth_offset) { _camera_offset = camera_offset; + _depth_offset = depth_offset; return *this; } @@ -58,11 +59,12 @@ tile_shader& tile_shader::set_tint(const Vector4& tint) void tile_shader::_draw() { fm_assert(std::fabs(_camera_offset[0]) < 1 << 24 && std::fabs(_camera_offset[1]) < 1 << 24); + fm_assert(std::fabs(_depth_offset) < 1 << 24); if (_tint != _real_tint) setUniform(TintUniform, _real_tint = _tint); - if (const auto offset = Vector2{(float)_camera_offset[0], (float)_camera_offset[1]}; + if (const auto offset = Vector3((float)_camera_offset[0], (float)_camera_offset[1], _depth_offset); offset != _real_camera_offset) { _real_camera_offset = offset; @@ -72,11 +74,7 @@ void tile_shader::_draw() float tile_shader::depth_value(const local_coords& xy, float offset) noexcept { - constexpr float max = (TILE_MAX_DIM+1)*(TILE_MAX_DIM+1) * .5f; - constexpr float min = -1 + 1.f/256; - float value = min + (xy.to_index() + offset)/max; - fm_assert(value > -1 && value < 1); - return value; + return (xy.to_index() + offset)*depth_tile_size; } } // namespace floormat diff --git a/shaders/tile.hpp b/shaders/tile.hpp index 72f36c40..d6eb7cca 100644 --- a/shaders/tile.hpp +++ b/shaders/tile.hpp @@ -1,5 +1,6 @@ #pragma once #include "compat/defs.hpp" +#include "tile-defs.hpp" #include <Magnum/GL/AbstractShaderProgram.h> #include <Magnum/Math/Vector2.h> #include <Magnum/Math/Vector3.h> @@ -24,9 +25,10 @@ struct tile_shader : GL::AbstractShaderProgram Vector2 scale() const { return _scale; } tile_shader& set_scale(const Vector2& scale); Vector2d camera_offset() const { return _camera_offset; } - tile_shader& set_camera_offset(Vector2d camera_offset); + tile_shader& set_camera_offset(const Vector2d& camera_offset, float depth_offset); Vector4 tint() const { return _tint; } tile_shader& set_tint(const Vector4& tint); + float depth_offset() const { return _depth_offset; } static float depth_value(const local_coords& xy, float offset = 0) noexcept; template<typename T = float> static constexpr Math::Vector2<T> project(const Math::Vector3<T>& pt); @@ -35,13 +37,16 @@ struct tile_shader : GL::AbstractShaderProgram template<typename T, typename... Xs> decltype(auto) draw(T&& mesh, Xs&&... xs); + static constexpr float depth_tile_size = 1.f/(256 * TILE_COUNT); + private: void _draw(); Vector2d _camera_offset; Vector4 _tint, _real_tint; Vector2 _scale; - Vector2 _real_camera_offset; + Vector3 _real_camera_offset; + float _depth_offset = 0; enum { ScaleUniform = 0, OffsetUniform = 1, TintUniform = 2, }; }; diff --git a/shaders/tile.vert b/shaders/tile.vert index ad038e6d..a539ed6b 100644 --- a/shaders/tile.vert +++ b/shaders/tile.vert @@ -1,7 +1,7 @@ precision highp float; layout (location = 0) uniform vec2 scale; -layout (location = 1) uniform vec2 offset; +layout (location = 1) uniform vec3 offset; layout (location = 0) in vec4 position; layout (location = 1) in vec2 texcoords; @@ -10,6 +10,6 @@ noperspective out vec2 frag_texcoords; void main() { float x = -position.y, y = -position.x, z = position.z; - gl_Position = vec4((x-y+offset.x)*scale.x, ((x+y+z*2)*.59-offset.y)*scale.y, depth, 1); + gl_Position = vec4((x-y+offset.x)*scale.x, ((x+y+z*2)*.59-offset.y)*scale.y, offset.z + depth, 1); frag_texcoords = texcoords; } diff --git a/src/camera-offset.cpp b/src/camera-offset.cpp index 335a9b65..7c5be7f3 100644 --- a/src/camera-offset.cpp +++ b/src/camera-offset.cpp @@ -6,18 +6,22 @@ namespace floormat { static_assert(sizeof(short) == 2); -with_shifted_camera_offset::with_shifted_camera_offset(tile_shader& shader, short x, short y) : +with_shifted_camera_offset::with_shifted_camera_offset(tile_shader& shader, chunk_coords c, chunk_coords first, chunk_coords last) : _shader{shader}, - _offset{shader.camera_offset()} + _camera{shader.camera_offset()}, + _depth{shader.depth_offset()} { constexpr auto chunk_size = TILE_MAX_DIM20d*dTILE_SIZE; - const auto offset = _offset + tile_shader::project(Vector3d(x, y, 0) * chunk_size); - _shader.set_camera_offset(offset); + const auto offset = _camera + tile_shader::project(Vector3d(c.x, c.y, 0) * chunk_size); + const auto len_x = (float)(last.x - first.x), cx = (float)(c.x - first.x), cy = (float)(c.y - first.y); + const float depth_offset = _depth + shader.depth_tile_size*(cy*TILE_MAX_DIM*len_x*TILE_MAX_DIM + cx*TILE_MAX_DIM); + + _shader.set_camera_offset(offset, depth_offset); } with_shifted_camera_offset::~with_shifted_camera_offset() { - _shader.set_camera_offset(_offset); + _shader.set_camera_offset(_camera, _depth); } } // namespace floormat diff --git a/src/camera-offset.hpp b/src/camera-offset.hpp index 0a44ee30..ef098694 100644 --- a/src/camera-offset.hpp +++ b/src/camera-offset.hpp @@ -9,12 +9,12 @@ struct tile_shader; struct with_shifted_camera_offset final { - explicit with_shifted_camera_offset(tile_shader& shader, short x, short y); - explicit with_shifted_camera_offset(tile_shader& shader, chunk_coords c) : with_shifted_camera_offset(shader, c.x, c.y) {} + explicit with_shifted_camera_offset(tile_shader& shader, chunk_coords c, chunk_coords first, chunk_coords last); ~with_shifted_camera_offset(); private: tile_shader& _shader; // NOLINT - Vector2d _offset; + Vector2d _camera; + float _depth; }; } // namespace floormat |