diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2022-10-02 20:08:39 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-10-02 20:08:39 +0200 |
commit | fb9ee17767d7d1e06f3cfa3b8cbc3956d081c118 (patch) | |
tree | 87d28c3be9b94a3bac59ab586f795ea05d4789ad | |
parent | fc723316422dec454654e2aa6cbc438b4f714d0b (diff) |
a
-rw-r--r-- | floor-mesh.cpp | 5 | ||||
-rw-r--r-- | wall-mesh.cpp | 81 | ||||
-rw-r--r-- | wall-mesh.hpp | 46 |
3 files changed, 127 insertions, 5 deletions
diff --git a/floor-mesh.cpp b/floor-mesh.cpp index 66aa2b12..0886dc34 100644 --- a/floor-mesh.cpp +++ b/floor-mesh.cpp @@ -30,7 +30,6 @@ void floor_mesh::draw(tile_shader& shader, chunk& c) set_tile(data[idx], x); }); _vertex_buffer.setData(data, Magnum::GL::BufferUsage::DynamicDraw); -#if 1 Magnum::GL::MeshView mesh{_mesh}; mesh.setCount(quad_index_count); tile_atlas* last_tile_atlas = nullptr; @@ -43,10 +42,6 @@ void floor_mesh::draw(tile_shader& shader, chunk& c) } shader.draw(mesh); }); -#else - c[0].ground_image.atlas->texture().bind(0); - shader.draw(_mesh); -#endif } static auto make_index_array() diff --git a/wall-mesh.cpp b/wall-mesh.cpp index 3dcbb38a..6ae45438 100644 --- a/wall-mesh.cpp +++ b/wall-mesh.cpp @@ -1,5 +1,86 @@ #include "wall-mesh.hpp" +#include "tile-atlas.hpp" +#include "shaders/tile-shader.hpp" +#include "chunk.hpp" +#include <Magnum/GL/MeshView.h> namespace Magnum::Examples { +#if 0 +static auto make_wall_positions_array() +{ + constexpr float X = TILE_SIZE[0], Y = TILE_SIZE[1], Z = TILE_SIZE[2]; + Vector3 center {(float)(X*i), (float)(Y*j), 0}; + array[k] = { tile_atlas::wall_quad_N(center, {X, Y, Z}) }; + array[k+1] = { tile_atlas::wall_quad_W(center, {X, Y, Z}) }; +} +#endif + +wall_mesh::wall_mesh() +{ + _mesh.setCount((int)(_index_data.size() * _index_data[0].size())) + .addVertexBuffer(_vertex_buffer, 0, tile_shader::TextureCoordinates{}, tile_shader::Position{}) + .setIndexBuffer(_index_buffer, 0, GL::MeshIndexType::UnsignedShort); + CORRADE_INTERNAL_ASSERT(_mesh.isIndexed()); +} + +void wall_mesh::add_wall(vertex_array& data, std::size_t& pos_, tile_image& img, const position_array& positions) +{ + const auto pos = pos_++; + CORRADE_INTERNAL_ASSERT(pos < data.size()); + auto texcoords = img.atlas->texcoords_for_id(img.variant); + for (std::size_t i = 0; i < 4; i++) + data[pos][i] = { texcoords[i], positions[i] }; +} + +void wall_mesh::add_tile(vertex_array& data, std::size_t& pos, tile& x, local_coords pt) +{ + constexpr float X = TILE_SIZE[0], Y = TILE_SIZE[1], Z = TILE_SIZE[2]; + constexpr Vector3 size = {X, Y, Z}; + Vector3 center{(float)(X*pt.x), (float)(Y*pt.y), 0}; + + if (auto& wall = x.wall_north; wall.atlas) + add_wall(data, pos, wall, tile_atlas::wall_quad_N(center, size)); + if (auto& wall = x.wall_west; wall.atlas) + add_wall(data, pos, wall, tile_atlas::wall_quad_W(center, size)); +} + +void wall_mesh::draw(tile_shader& shader, chunk& c) +{ + { + vertex_array data; + std::size_t pos = 0; + c.foreach_tile([&](tile& x, std::size_t, local_coords pt) { + add_tile(data, pos, x, pt); + }); + _vertex_buffer.setData(data, Magnum::GL::BufferUsage::DynamicDraw); + } + { + tile_atlas* last_tile_atlas = nullptr; + Magnum::GL::MeshView mesh{_mesh}; + mesh.setCount(quad_index_count); + c.foreach_tile([&](tile& x, std::size_t i, local_coords) { + mesh.setIndexRange((int)(i*quad_index_count), 0, quad_index_count*COUNT - 1); + if (auto* atlas = x.ground_image.atlas.get(); atlas != last_tile_atlas) + { + atlas->texture().bind(0); + last_tile_atlas = atlas; + } + shader.draw(mesh); + }); + } +} + +decltype(wall_mesh::_index_data) wall_mesh::make_index_array() +{ + constexpr auto quad_index_count = std::tuple_size_v<decltype(tile_atlas::indices(0))>; + std::array<std::array<UnsignedShort, quad_index_count>, COUNT> array; // NOLINT(cppcoreguidelines-pro-type-member-init) + + for (std::size_t i = 0; i < std::size(array); i++) + array[i] = tile_atlas::indices(i); + return array; +} + +const auto wall_mesh::_index_data = wall_mesh::make_index_array(); + } // namespace Magnum::Examples diff --git a/wall-mesh.hpp b/wall-mesh.hpp index b1f7be7e..905e7acc 100644 --- a/wall-mesh.hpp +++ b/wall-mesh.hpp @@ -1,5 +1,51 @@ #pragma once +#include "tile.hpp" +#include <array> +#include <Corrade/Containers/ArrayViewStl.h> +#include <Magnum/Magnum.h> +#include <Magnum/Math/Vector2.h> +#include <Magnum/GL/Mesh.h> +#include <Magnum/GL/Buffer.h> + namespace Magnum::Examples { +struct tile_shader; +struct chunk; + +struct wall_mesh final +{ + wall_mesh(); + wall_mesh(wall_mesh&&) = delete; + wall_mesh(const wall_mesh&) = delete; + + void draw(tile_shader& shader, chunk& c); + +private: + static constexpr auto COUNT = TILE_MAX_DIM*2 * TILE_MAX_DIM*2; + static constexpr auto quad_index_count = 6; + + using texcoords_array = std::array<Vector2, 4>; + using position_array = std::array<Vector3, 4>; + + struct vertex final { + typename texcoords_array::value_type texcoords; + typename position_array::value_type position; + }; + + using quad = std::array<vertex, 4>; + using index_type = std::array<UnsignedShort, 6>; + using vertex_array = std::array<quad, COUNT>; + + static void add_tile(vertex_array& data, std::size_t& pos, tile& x, local_coords pt); + static void add_wall(vertex_array& data, std::size_t& pos, tile_image& img, const position_array& positions); + + GL::Mesh _mesh; + GL::Buffer _vertex_buffer{{}, Magnum::GL::BufferUsage::DynamicDraw}, + _index_buffer{_index_data, Magnum::GL::BufferUsage::StaticDraw}; + + static const std::array<index_type, COUNT> _index_data; + static decltype(_index_data) make_index_array(); +}; + } // namespace Magnum::Examples |