summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2022-11-29 22:15:27 +0100
committerStanislaw Halik <sthalik@misaki.pl>2022-11-29 22:32:46 +0100
commit9c5027215e1052adb0131362207b78ec89822985 (patch)
treead928799caedab4fa497802e8981db9dc66fcc76
parent2659fae8c838601282b9b90d5e0dc8b1da3f3f2b (diff)
fix z value discontinuity on chunk boundaries
-rw-r--r--editor/camera.cpp4
-rw-r--r--main/draw.cpp24
-rw-r--r--main/main-impl.hpp2
-rw-r--r--shaders/tile.cpp14
-rw-r--r--shaders/tile.hpp9
-rw-r--r--shaders/tile.vert4
-rw-r--r--src/camera-offset.cpp14
-rw-r--r--src/camera-offset.hpp6
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