diff options
-rw-r--r-- | draw/anim.cpp | 10 | ||||
-rw-r--r-- | draw/anim.hpp | 8 | ||||
-rw-r--r-- | draw/wall.cpp | 19 | ||||
-rw-r--r-- | draw/wall.hpp | 9 | ||||
-rw-r--r-- | draw/wireframe.cpp | 9 | ||||
-rw-r--r-- | draw/wireframe.hpp | 2 | ||||
-rw-r--r-- | editor/draw.cpp | 2 | ||||
-rw-r--r-- | editor/editor.cpp | 2 | ||||
-rw-r--r-- | editor/imgui.cpp | 8 | ||||
-rw-r--r-- | main/draw.cpp | 43 | ||||
-rw-r--r-- | shaders/tile.cpp | 10 | ||||
-rw-r--r-- | shaders/tile.frag | 1 | ||||
-rw-r--r-- | shaders/tile.hpp | 8 | ||||
-rw-r--r-- | shaders/tile.vert | 3 | ||||
-rw-r--r-- | src/chunk.cpp | 12 |
15 files changed, 99 insertions, 47 deletions
diff --git a/draw/anim.cpp b/draw/anim.cpp index 1a02ad93..dac23566 100644 --- a/draw/anim.cpp +++ b/draw/anim.cpp @@ -9,8 +9,7 @@ namespace floormat { anim_mesh::anim_mesh() { _mesh.setCount(6) - .addVertexBuffer(_vertex_buffer, 0, tile_shader::TextureCoordinates{}) - .addVertexBuffer(_positions_buffer, 0, tile_shader::Position{}) + .addVertexBuffer(_vertex_buffer, 0, tile_shader::Position{}, tile_shader::TextureCoordinates{}, tile_shader::Depth{}) .setIndexBuffer(_index_buffer, 0, GL::MeshIndexType::UnsignedShort); CORRADE_INTERNAL_ASSERT(_mesh.isIndexed()); } @@ -27,9 +26,12 @@ void anim_mesh::draw(tile_shader& shader, const anim_atlas& atlas, rotation r, s { const auto center = Vector3(xy.x, xy.y, 0.f) * TILE_SIZE; const auto pos = atlas.frame_quad(center, r, frame); - _positions_buffer.setSubData(0, pos); const auto texcoords = atlas.texcoords_for_frame(r, frame); - _vertex_buffer.setSubData(0, texcoords); + const float depth = tile_shader::depth_value(xy); + quad_data array; + for (std::size_t i = 0; i < 4; i++) + array[i] = { pos[i], texcoords[i], depth }; + _vertex_buffer.setSubData(0, array); shader.draw(_mesh); } diff --git a/draw/anim.hpp b/draw/anim.hpp index 04fd92c8..163c5b1a 100644 --- a/draw/anim.hpp +++ b/draw/anim.hpp @@ -24,14 +24,18 @@ struct anim_mesh final void draw(tile_shader& shader, const anim_atlas& atlas, rotation r, std::size_t frame, local_coords xy); private: - struct vertex_data final { Vector2 texcoords; }; + struct vertex_data final { + Vector3 position; + Vector2 texcoords; + float depth = -1; + }; using quad_data = std::array<vertex_data, 4>; static std::array<UnsignedShort, 6> make_index_array(); GL::Mesh _mesh; GL::Buffer _vertex_buffer{quad_data{}, Magnum::GL::BufferUsage::DynamicDraw}, - _index_buffer{make_index_array()}, _positions_buffer{std::array<Vector3, 4>{}}; + _index_buffer{make_index_array()}; }; } // namespace floormat diff --git a/draw/wall.cpp b/draw/wall.cpp index 4c25b267..0096946e 100644 --- a/draw/wall.cpp +++ b/draw/wall.cpp @@ -15,7 +15,7 @@ wall_mesh::wall_mesh() { _mesh.setCount((int)(quad_index_count * COUNT)) .addVertexBuffer(_vertex_buffer, 0, tile_shader::TextureCoordinates{}) - .addVertexBuffer(_positions_buffer, 0, tile_shader::Position{}) + .addVertexBuffer(_constant_buffer, 0, tile_shader::Position{}, tile_shader::Depth{}) .setIndexBuffer(_index_buffer, 0, GL::MeshIndexType::UnsignedShort); CORRADE_INTERNAL_ASSERT(_mesh.isIndexed()); } @@ -94,16 +94,23 @@ std::array<std::array<UnsignedShort, 6>, wall_mesh::COUNT> wall_mesh::make_index return array; } -std::array<std::array<Vector3, 4>, wall_mesh::COUNT> wall_mesh::make_position_array() +auto wall_mesh::make_constant_array() -> std::array<std::array<constant, 4>, wall_mesh::COUNT> { - std::array<std::array<Vector3, 4>, COUNT> array; + std::array<std::array<constant, 4>, COUNT> array; for (std::uint8_t j = 0; j < TILE_MAX_DIM; j++) for (std::uint8_t i = 0; i < TILE_MAX_DIM; i++) { - const std::size_t idx = (j*TILE_MAX_DIM + i) * 2u; + const local_coords coord{i, j}; + const std::size_t idx = coord.to_index() * 2u; const auto center = Vector3(i, j, 0) * TILE_SIZE; - array[idx + 0] = tile_atlas::wall_quad_N(center, TILE_SIZE); - array[idx + 1] = tile_atlas::wall_quad_W(center, TILE_SIZE); + auto wall_n_pos = tile_atlas::wall_quad_N(center, TILE_SIZE); + auto wall_w_pos = tile_atlas::wall_quad_W(center, TILE_SIZE); + auto depth = tile_shader::depth_value(coord); + for (std::size_t k = 0; k < 4; k++) + { + array[idx + 0][k] = { wall_n_pos[k], depth, }; + array[idx + 1][k] = { wall_w_pos[k], depth, }; + } } return array; } diff --git a/draw/wall.hpp b/draw/wall.hpp index 81c6b60e..d65744fd 100644 --- a/draw/wall.hpp +++ b/draw/wall.hpp @@ -28,6 +28,11 @@ private: Vector2 texcoords; }; + struct constant final { + Vector3 position; + float depth = -1; + }; + using quad = std::array<vertex, 4>; using vertex_array = std::array<quad, COUNT>; using texture_array = std::array<GL::Texture2D*, COUNT>; @@ -40,9 +45,9 @@ private: GL::Mesh _mesh; GL::Buffer _vertex_buffer{vertex_array{}, Magnum::GL::BufferUsage::DynamicDraw}, _index_buffer{make_index_array()}, - _positions_buffer{make_position_array()}; + _constant_buffer{make_constant_array()}; static std::array<std::array<UnsignedShort, 6>, COUNT> make_index_array(); - static std::array<std::array<Vector3, 4>, COUNT> make_position_array(); + static std::array<std::array<constant, 4>, COUNT> make_constant_array(); }; } // namespace floormat diff --git a/draw/wireframe.cpp b/draw/wireframe.cpp index 053fce7b..bf024f9e 100644 --- a/draw/wireframe.cpp +++ b/draw/wireframe.cpp @@ -27,16 +27,21 @@ GL::Texture2D mesh_base::make_constant_texture() return tex; } +struct constant_buf { + Vector2 texcoords; + float depth = 1; +}; + mesh_base::mesh_base(GL::MeshPrimitive primitive, ArrayView<const void> index_data, std::size_t num_vertices, std::size_t num_indexes) : _vertex_buffer{Containers::Array<Vector3>{ValueInit, num_vertices}, GL::BufferUsage::DynamicDraw}, - _texcoords_buffer{Containers::Array<Vector2>{ValueInit, num_vertices}}, + _constant_buffer{Containers::Array<constant_buf>{ValueInit, num_vertices}}, _index_buffer{num_indexes == 0 ? GL::Buffer{NoCreate} : GL::Buffer{index_data}} { _mesh.setCount((int)(num_indexes > 0 ? num_indexes : num_vertices)) .setPrimitive(primitive) .addVertexBuffer(_vertex_buffer, 0, tile_shader::Position{}) - .addVertexBuffer(_texcoords_buffer, 0, tile_shader::TextureCoordinates{}); + .addVertexBuffer(_constant_buffer, 0, tile_shader::TextureCoordinates{}, tile_shader::Depth{}); if (num_indexes > 0) _mesh.setIndexBuffer(_index_buffer, 0, GL::MeshIndexType::UnsignedShort); } diff --git a/draw/wireframe.hpp b/draw/wireframe.hpp index 1d58ff43..400fbee7 100644 --- a/draw/wireframe.hpp +++ b/draw/wireframe.hpp @@ -25,7 +25,7 @@ concept traits = requires (const T& x) { struct mesh_base { static GL::Texture2D make_constant_texture(); - GL::Buffer _vertex_buffer{{}, GL::BufferUsage::DynamicDraw}, _texcoords_buffer, _index_buffer; + GL::Buffer _vertex_buffer{{}, GL::BufferUsage::DynamicDraw}, _constant_buffer, _index_buffer; GL::Texture2D _texture = make_constant_texture(); GL::Mesh _mesh; diff --git a/editor/draw.cpp b/editor/draw.cpp index 89613d37..ad634815 100644 --- a/editor/draw.cpp +++ b/editor/draw.cpp @@ -9,8 +9,6 @@ namespace floormat { void app::draw_cursor() { - GL::Renderer::disable(GL::Renderer::Feature::DepthTest); - constexpr float LINE_WIDTH = 2; if (cursor.tile && !cursor.in_imgui) diff --git a/editor/editor.cpp b/editor/editor.cpp index 9676a22d..1bba44d6 100644 --- a/editor/editor.cpp +++ b/editor/editor.cpp @@ -82,7 +82,7 @@ void editor::on_mouse_move(world& world, global_coords& pos, int mods) void editor::on_click_(world& world, global_coords pos, button b) { if (auto* mode = current_tile_editor(); mode != nullptr) - if (auto opt = mode->get_selected(); opt) + if (auto opt = mode->get_selected(); opt || b == button::remove) { switch (b) { diff --git a/editor/imgui.cpp b/editor/imgui.cpp index 5df5df64..84827ba3 100644 --- a/editor/imgui.cpp +++ b/editor/imgui.cpp @@ -19,14 +19,6 @@ void app::init_imgui(Vector2i size) void app::render_menu() { - GL::Renderer::setBlendEquation(GL::Renderer::BlendEquation::Add, GL::Renderer::BlendEquation::Add); - GL::Renderer::setBlendFunction(GL::Renderer::BlendFunction::SourceAlpha, GL::Renderer::BlendFunction::OneMinusSourceAlpha); - GL::Renderer::enable(GL::Renderer::Feature::Blending); - - GL::Renderer::enable(GL::Renderer::Feature::ScissorTest); - GL::Renderer::disable(GL::Renderer::Feature::FaceCulling); - GL::Renderer::disable(GL::Renderer::Feature::DepthTest); - _imgui.drawFrame(); } diff --git a/main/draw.cpp b/main/draw.cpp index ca2e00a1..2b17ce9b 100644 --- a/main/draw.cpp +++ b/main/draw.cpp @@ -22,16 +22,30 @@ void main_impl::recalc_viewport(Vector2i size) noexcept _msaa_framebuffer.setViewport({{}, size}); else _msaa_framebuffer = GL::Framebuffer{{{}, size}}; + // --- color --- _msaa_color = Magnum::GL::Renderbuffer{}; const int samples = std::min(_msaa_color.maxSamples(), (int)s.msaa_samples); _msaa_color.setStorageMultisample(samples, GL::RenderbufferFormat::RGBA8, size); _msaa_framebuffer.attachRenderbuffer(GL::Framebuffer::ColorAttachment{0}, _msaa_color); + // --- depth --- _msaa_depth = Magnum::GL::Renderbuffer{}; _msaa_depth.setStorageMultisample(samples, GL::RenderbufferFormat::DepthStencil, size); _msaa_framebuffer.attachRenderbuffer(GL::Framebuffer::BufferAttachment::DepthStencil, _msaa_depth); - // -- done --- + + // -- state --- + using R = GL::Renderer; + GL::Renderer::setBlendEquation(R::BlendEquation::Add, R::BlendEquation::Add); + GL::Renderer::setBlendFunction(R::BlendFunction::SourceAlpha, R::BlendFunction::OneMinusSourceAlpha); + GL::Renderer::disable(R::Feature::FaceCulling); + GL::Renderer::disable(R::Feature::DepthTest); + GL::Renderer::enable(R::Feature::Blending); + GL::Renderer::enable(R::Feature::ScissorTest); + GL::Renderer::setDepthFunction(R::DepthFunction::Greater); + GL::Renderer::setScissor({{}, size}); + + // -- user-- app.on_viewport_event(size); } @@ -69,8 +83,6 @@ void main_impl::draw_world() noexcept auto [minx, maxx, miny, maxy] = get_draw_bounds(); const auto sz = windowSize(); - GL::Renderer::disable(GL::Renderer::Feature::DepthTest); - for (std::int16_t y = miny; y <= maxy; y++) for (std::int16_t x = minx; x <= maxx; x++) { @@ -82,8 +94,13 @@ void main_impl::draw_world() noexcept _floor_mesh.draw(_shader, _world[c]); } - //GL::Renderer::enable(GL::Renderer::Feature::DepthTest); - + GL::Renderer::enable(GL::Renderer::Feature::DepthTest); + constexpr float clear_depth = 0; +#ifdef FM_SKIP_MSAA + GL::defaultFramebuffer.clearDepthStencil(clear_depth, 0); +#else + _msaa_framebuffer.clearDepthStencil(clear_depth, 0); +#endif for (std::int16_t y = miny; y <= maxy; y++) for (std::int16_t x = minx; x <= maxx; x++) { @@ -92,6 +109,7 @@ void main_impl::draw_world() noexcept if (check_chunk_visible(_shader.camera_offset(), sz)) _wall_mesh.draw(_shader, _world[c]); } + GL::Renderer::disable(GL::Renderer::Feature::DepthTest); } bool main_impl::check_chunk_visible(const Vector2d& offset, const Vector2i& size) noexcept @@ -136,18 +154,21 @@ void main_impl::drawEvent() _shader.set_tint({1, 1, 1, 1}); { - using fc = GL::FramebufferClear; - constexpr auto mask = fc::Color | fc::Depth | fc::Stencil; - GL::defaultFramebuffer.clear(mask); -#ifndef FM_SKIP_MSAA - _msaa_framebuffer.clear(mask); + using namespace Math::Literals; + const auto clear_color = 0x222222ff_rgbaf; +#ifdef FM_SKIP_MSAA + GL::defaultFramebuffer.clearColor(clear_color); +#else + _msaa_framebuffer.clearColor(0, clear_color); _msaa_framebuffer.bind(); #endif draw_world(); app.draw_msaa(); #ifndef FM_SKIP_MSAA GL::defaultFramebuffer.bind(); - GL::Framebuffer::blit(_msaa_framebuffer, GL::defaultFramebuffer, {{}, windowSize()}, GL::FramebufferBlit{(unsigned)mask}); + using Blit = GL::FramebufferBlit; + constexpr auto blit_mask = Blit::Color /* | Blit::Depth | Blit::Stencil */; + GL::Framebuffer::blit(_msaa_framebuffer, GL::defaultFramebuffer, {{}, windowSize()}, blit_mask); #endif } diff --git a/shaders/tile.cpp b/shaders/tile.cpp index 2fb37cd8..c8261acd 100644 --- a/shaders/tile.cpp +++ b/shaders/tile.cpp @@ -1,6 +1,7 @@ #include "shaders/tile.hpp" #include "loader.hpp" #include "compat/assert.hpp" +#include "local-coords.hpp" #include <Magnum/Math/Vector4.h> #include <Magnum/GL/Context.h> #include <Magnum/GL/Shader.h> @@ -65,4 +66,13 @@ void tile_shader::_draw() } } +float tile_shader::depth_value(const local_coords& xy) 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()/max; + fm_assert(value > -1 && value < 1); + return value; +} + } // namespace floormat diff --git a/shaders/tile.frag b/shaders/tile.frag index 64372b7b..a233825e 100644 --- a/shaders/tile.frag +++ b/shaders/tile.frag @@ -5,6 +5,7 @@ layout (location = 2) uniform vec4 tint = vec4(1, 1, 1, 1); noperspective in vec2 frag_texcoords; out vec4 color; +//layout (depth_greater) out float gl_FragDepth; void main() { color = texture(sampler, frag_texcoords) * tint; diff --git a/shaders/tile.hpp b/shaders/tile.hpp index 2be1414a..8a45e1e7 100644 --- a/shaders/tile.hpp +++ b/shaders/tile.hpp @@ -7,10 +7,13 @@ namespace floormat { +struct local_coords; + struct tile_shader : GL::AbstractShaderProgram { - typedef GL::Attribute<0, Vector3> Position; - typedef GL::Attribute<1, Vector2> TextureCoordinates; + using Position = GL::Attribute<0, Vector3>; + using TextureCoordinates = GL::Attribute<1, Vector2>; + using Depth = GL::Attribute<2, float>; fm_DECLARE_DEFAULT_MOVE_ASSIGNMENT_(tile_shader); fm_DECLARE_DELETED_COPY_ASSIGNMENT(tile_shader); @@ -24,6 +27,7 @@ struct tile_shader : GL::AbstractShaderProgram tile_shader& set_camera_offset(Vector2d camera_offset); Vector4 tint() const { return _tint; } tile_shader& set_tint(const Vector4& tint); + static float depth_value(const local_coords& xy) noexcept; template<typename T = float> static constexpr Math::Vector2<T> project(const Math::Vector3<T>& pt); template<typename T = float> static constexpr Math::Vector2<T> unproject(const Math::Vector2<T>& px); diff --git a/shaders/tile.vert b/shaders/tile.vert index b512b7ac..ad038e6d 100644 --- a/shaders/tile.vert +++ b/shaders/tile.vert @@ -5,10 +5,11 @@ layout (location = 1) uniform vec2 offset; layout (location = 0) in vec4 position; layout (location = 1) in vec2 texcoords; +layout (location = 2) in float depth; 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, 0, 1); + gl_Position = vec4((x-y+offset.x)*scale.x, ((x+y+z*2)*.59-offset.y)*scale.y, depth, 1); frag_texcoords = texcoords; } diff --git a/src/chunk.cpp b/src/chunk.cpp index 973a1a5d..0cfb4959 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -52,6 +52,7 @@ auto chunk::ensure_ground_mesh() noexcept -> mesh_tuple struct vertex { Vector3 position; Vector2 texcoords; + float depth = -1; }; std::array<std::array<vertex, 4>, TILE_COUNT> vertexes; for (std::size_t k = 0; k < TILE_COUNT; k++) @@ -61,18 +62,19 @@ auto chunk::ensure_ground_mesh() noexcept -> mesh_tuple vertexes[k] = {}; else { - const std::uint8_t x = i % TILE_MAX_DIM, y = i / TILE_MAX_DIM; - auto quad = atlas->floor_quad(Vector3(x, y, 0) * TILE_SIZE, TILE_SIZE2); - auto texcoords = atlas->texcoords_for_id(_ground_variants[i] % atlas->num_tiles()); + const local_coords pos{i}; + const auto quad = atlas->floor_quad(Vector3(pos.x, pos.y, 0) * TILE_SIZE, TILE_SIZE2); + const auto texcoords = atlas->texcoords_for_id(_ground_variants[i] % atlas->num_tiles()); + const float depth = tile_shader::depth_value(pos); auto& v = vertexes[k]; for (std::size_t j = 0; j < 4; j++) - v[j] = { quad[j], texcoords[j] }; + v[j] = { quad[j], texcoords[j], depth }; } } constexpr auto indexes = make_index_array(); GL::Mesh mesh{GL::MeshPrimitive::Triangles}; - mesh.addVertexBuffer(GL::Buffer{vertexes}, 0, tile_shader::Position{}, tile_shader::TextureCoordinates{}) + mesh.addVertexBuffer(GL::Buffer{vertexes}, 0, tile_shader::Position{}, tile_shader::TextureCoordinates{}, tile_shader::Depth{}) .setIndexBuffer(GL::Buffer{indexes}, 0, GL::MeshIndexType::UnsignedShort) .setCount(6 * TILE_COUNT); ground_mesh = Utility::move(mesh); |