From 89acc4653fe7ea3a76dd49711b3ac6b704ed509d Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Thu, 6 Oct 2022 09:49:23 +0200 Subject: a --- CMakeLists.txt | 17 ++-------- chunk.cpp | 5 --- chunk.hpp | 60 ----------------------------------- floor-mesh.cpp | 72 ------------------------------------------ floor-mesh.hpp | 37 ---------------------- loader.cpp | 6 ---- loader.hpp | 32 ------------------- main/CMakeLists.txt | 6 ++-- serialize/tile-atlas.cpp | 2 +- src/CMakeLists.txt | 12 +++++++ src/chunk.cpp | 5 +++ src/chunk.hpp | 60 +++++++++++++++++++++++++++++++++++ src/floor-mesh.cpp | 72 ++++++++++++++++++++++++++++++++++++++++++ src/floor-mesh.hpp | 37 ++++++++++++++++++++++ src/loader.cpp | 6 ++++ src/loader.hpp | 32 +++++++++++++++++++ src/tile-atlas.cpp | 39 +++++++++++++++++++++++ src/tile-atlas.hpp | 74 +++++++++++++++++++++++++++++++++++++++++++ src/tile.cpp | 11 +++++++ src/tile.hpp | 40 +++++++++++++++++++++++ src/wall-mesh.cpp | 82 ++++++++++++++++++++++++++++++++++++++++++++++++ src/wall-mesh.hpp | 47 +++++++++++++++++++++++++++ tile-atlas.cpp | 39 ----------------------- tile-atlas.hpp | 74 ------------------------------------------- tile.cpp | 11 ------- tile.hpp | 40 ----------------------- wall-mesh.cpp | 82 ------------------------------------------------ wall-mesh.hpp | 47 --------------------------- 28 files changed, 524 insertions(+), 523 deletions(-) delete mode 100644 chunk.cpp delete mode 100644 chunk.hpp delete mode 100644 floor-mesh.cpp delete mode 100644 floor-mesh.hpp delete mode 100644 loader.cpp delete mode 100644 loader.hpp create mode 100644 src/CMakeLists.txt create mode 100644 src/chunk.cpp create mode 100644 src/chunk.hpp create mode 100644 src/floor-mesh.cpp create mode 100644 src/floor-mesh.hpp create mode 100644 src/loader.cpp create mode 100644 src/loader.hpp create mode 100644 src/tile-atlas.cpp create mode 100644 src/tile-atlas.hpp create mode 100644 src/tile.cpp create mode 100644 src/tile.hpp create mode 100644 src/wall-mesh.cpp create mode 100644 src/wall-mesh.hpp delete mode 100644 tile-atlas.cpp delete mode 100644 tile-atlas.hpp delete mode 100644 tile.cpp delete mode 100644 tile.hpp delete mode 100644 wall-mesh.cpp delete mode 100644 wall-mesh.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index dc24f387..07bb26ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,24 +56,11 @@ if(NOT BOOTSTRAP_DEPENDS) find_package(MagnumIntegration QUIET REQUIRED COMPONENTS Glm) include_directories(.) + include_directories(src) - file(GLOB sources "*.cpp" "shaders/*.cpp" "serialize/*.cpp" CONFIGURE_ARGS) - add_library(${PROJECT_NAME} STATIC "${sources}") - target_link_libraries( - ${PROJECT_NAME} PUBLIC - Magnum::GL - Magnum::Magnum - Magnum::Shaders - nlohmann_json::nlohmann_json - ) - target_include_directories(${PROJECT_NAME} PRIVATE ${GLM_INCLUDE_DIRS}) - target_include_directories(${PROJECT_NAME} PRIVATE magnum-integration/src) - + add_subdirectory(src) add_subdirectory(main) add_subdirectory(anim-crop-tool) - install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin) - install(DIRECTORY images DESTINATION /src) - install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin) install(DIRECTORY images DESTINATION "share/${PROJECT_NAME}") endif() diff --git a/chunk.cpp b/chunk.cpp deleted file mode 100644 index 221f8132..00000000 --- a/chunk.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "chunk.hpp" - -namespace Magnum::Examples { - -} // namespace Magnum::Examples diff --git a/chunk.hpp b/chunk.hpp deleted file mode 100644 index 829ee0d3..00000000 --- a/chunk.hpp +++ /dev/null @@ -1,60 +0,0 @@ -#pragma once -#include "tile.hpp" -#include -#include - -namespace Magnum::Examples { - -struct chunk final -{ - constexpr tile& operator[](local_coords xy) { return tiles[xy.to_index()]; } - constexpr const tile& operator[](local_coords xy) const { return tiles[xy.to_index()]; } - constexpr tile& operator[](std::size_t i) { return tiles[i]; } - constexpr const tile& operator[](std::size_t i) const { return tiles[i]; } - - template - requires std::invocable - constexpr inline void foreach_tile(F&& fun) { foreach_tile_(std::forward(fun)); } - - template - requires std::invocable - constexpr inline void foreach_tile(F&& fun) const { foreach_tile_(std::forward(fun)); } - -private: - template - constexpr void foreach_tile_(F&& fun); - - std::array tiles = {}; -}; - -template -constexpr void chunk::foreach_tile_(F&& fun) -{ - constexpr auto N = TILE_MAX_DIM; - std::size_t k = 0; - for (std::size_t j = 0; j < N; j++) - for (std::size_t i = 0; i < N; i++, k++) - fun(const_cast(*this).tiles[k], k, - local_coords{(std::uint8_t)i, (std::uint8_t)j}); -} - -#if 0 -struct chunk_coords final { - std::int16_t x = 0, y = 0; - constexpr std::size_t to_index() const noexcept; - - static constexpr std::size_t max_bits = sizeof(chunk_coords::x)*8 * 3 / 4; - static_assert(max_bits*4/3/8 == sizeof(decltype(chunk_coords::x))); -}; -#endif - -#if 0 -struct global_coords final { - std::uint32_t x = 0, y = 0; - constexpr global_coords() noexcept = default; - constexpr global_coords(decltype(x) x, decltype(y) y) noexcept : x{x}, y{y} {} - constexpr global_coords(chunk_coords c, local_coords tile) noexcept; -}; -#endif - -} // namespace Magnum::Examples diff --git a/floor-mesh.cpp b/floor-mesh.cpp deleted file mode 100644 index 7156661e..00000000 --- a/floor-mesh.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "floor-mesh.hpp" -#include "shaders/tile-shader.hpp" -#include "tile.hpp" -#include "chunk.hpp" -#include "tile-atlas.hpp" -#include - -namespace Magnum::Examples { - -constexpr auto quad_index_count = 6; - -floor_mesh::floor_mesh() -{ - _mesh.setCount((int)(quad_index_count * TILE_COUNT)) - .addVertexBuffer(_positions_buffer, 0, tile_shader::Position{}) - .addVertexBuffer(_vertex_buffer, 0, tile_shader::TextureCoordinates{}) - .setIndexBuffer(_index_buffer, 0, GL::MeshIndexType::UnsignedShort); -} - -void floor_mesh::set_tile(quad_data& data, tile& x) -{ - CORRADE_INTERNAL_ASSERT(x.ground_image); - - auto texcoords = x.ground_image.atlas->texcoords_for_id(x.ground_image.variant); - for (size_t i = 0; i < 4; i++) - data[i] = { texcoords[i] }; -} - -void floor_mesh::draw(tile_shader& shader, chunk& c) -{ - std::array data; - c.foreach_tile([&](tile& x, std::size_t idx, local_coords) { - set_tile(data[idx], x); - }); - _vertex_buffer.setSubData(0, data); - Magnum::GL::MeshView mesh{_mesh}; - mesh.setCount(quad_index_count); - const tile_atlas* last_tile_atlas = nullptr; - c.foreach_tile([&](tile& x, std::size_t i, local_coords) { - mesh.setIndexRange((int)(i*quad_index_count), 0, quad_index_count*TILE_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); - }); -} - -std::array, TILE_COUNT> floor_mesh::make_index_array() -{ - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init) - std::array, TILE_COUNT> array; - for (std::size_t i = 0; i < std::size(array); i++) - array[i] = tile_atlas::indices(i); - return array; -} - -std::array, TILE_COUNT> floor_mesh::make_position_array() -{ - std::array, TILE_COUNT> array; - constexpr float X = TILE_SIZE[0], Y = TILE_SIZE[1]; - for (std::size_t j = 0, k = 0; j < TILE_MAX_DIM; j++) - for (std::size_t i = 0; i < TILE_MAX_DIM; i++, k++) - { - Vector3 center {(float)(X*i), (float)(Y*j), 0}; - array[k] = { tile_atlas::floor_quad(center, {X, Y}) }; - } - return array; -} - -} // namespace Magnum::Examples diff --git a/floor-mesh.hpp b/floor-mesh.hpp deleted file mode 100644 index 41351fd9..00000000 --- a/floor-mesh.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once -#include "tile.hpp" -#include -#include -#include -#include -#include -#include - -namespace Magnum::Examples { - -struct tile_shader; -struct chunk; - -struct floor_mesh final -{ - floor_mesh(); - floor_mesh(floor_mesh&&) = delete; - floor_mesh(const floor_mesh&) = delete; - - void draw(tile_shader& shader, chunk& c); - -private: - struct vertex_data final { Vector2 texcoords; }; - using quad_data = std::array; - - static std::array, TILE_COUNT> make_index_array(); - static std::array, TILE_COUNT> make_position_array(); - - GL::Mesh _mesh; - GL::Buffer _vertex_buffer{std::array{}, Magnum::GL::BufferUsage::DynamicDraw}, - _index_buffer{make_index_array()}, _positions_buffer{make_position_array()}; - - static void set_tile(quad_data& data, tile& x); -}; - -} // namespace Magnum::Examples diff --git a/loader.cpp b/loader.cpp deleted file mode 100644 index f6219350..00000000 --- a/loader.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "loader.hpp" - -namespace Magnum::Examples { -loader_::loader_() = default; -loader_::~loader_() = default; -} // namespace Magnum::Examples diff --git a/loader.hpp b/loader.hpp deleted file mode 100644 index 49299bb6..00000000 --- a/loader.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include -#include - -#include -#include -#include - -namespace Magnum::Examples { - -struct tile_atlas; - -struct loader_ -{ - virtual std::string shader(Containers::StringView filename) = 0; - virtual Trade::ImageData2D tile_texture(Containers::StringView filename) = 0; - virtual std::shared_ptr tile_atlas(Containers::StringView filename, Vector2ui size) = 0; - static void destroy(); - - loader_(const loader_&) = delete; - loader_& operator=(const loader_&) = delete; - - virtual ~loader_(); - -protected: - loader_(); -}; - -extern loader_& loader; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) - -} // namespace Magnum::Examples diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index cb3b1f2c..9614e17f 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,8 +1,10 @@ set(self "${PROJECT_NAME}-main") file(GLOB sources "*.cpp" CONFIGURE_ARGS) -link_libraries(${PROJECT_NAME} - Magnum::Application Magnum::Trade MagnumIntegration::Glm) +link_libraries(${PROJECT_NAME}) +link_libraries(Magnum::Application Magnum::Trade) + corrade_add_resource(res ../resources.conf) add_executable(${self} WIN32 "${sources}" "${res}") set_property(TARGET ${self} PROPERTY OUTPUT_NAME "${PROJECT_NAME}") +install(TARGETS ${self} RUNTIME DESTINATION bin) diff --git a/serialize/tile-atlas.cpp b/serialize/tile-atlas.cpp index 4a10d2c2..1aa0c14d 100644 --- a/serialize/tile-atlas.cpp +++ b/serialize/tile-atlas.cpp @@ -1,4 +1,4 @@ -#include "../tile-atlas.hpp" +#include "src/tile-atlas.hpp" #include "serialize/tile-atlas.hpp" #include "serialize/magnum-vector.hpp" #include "loader.hpp" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 00000000..e443a9df --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,12 @@ +set(self ${PROJECT_NAME}) +file(GLOB sources "*.cpp" "../shaders/*.cpp" "../serialize/*.cpp" CONFIGURE_ARGS) +add_library(${self} STATIC "${sources}") +target_link_libraries( + ${self} PUBLIC + Magnum::GL + Magnum::Magnum + Magnum::Shaders + nlohmann_json::nlohmann_json +) +target_include_directories(${self} PRIVATE ${GLM_INCLUDE_DIRS}) +target_include_directories(${self} PRIVATE magnum-integration/src) diff --git a/src/chunk.cpp b/src/chunk.cpp new file mode 100644 index 00000000..221f8132 --- /dev/null +++ b/src/chunk.cpp @@ -0,0 +1,5 @@ +#include "chunk.hpp" + +namespace Magnum::Examples { + +} // namespace Magnum::Examples diff --git a/src/chunk.hpp b/src/chunk.hpp new file mode 100644 index 00000000..829ee0d3 --- /dev/null +++ b/src/chunk.hpp @@ -0,0 +1,60 @@ +#pragma once +#include "tile.hpp" +#include +#include + +namespace Magnum::Examples { + +struct chunk final +{ + constexpr tile& operator[](local_coords xy) { return tiles[xy.to_index()]; } + constexpr const tile& operator[](local_coords xy) const { return tiles[xy.to_index()]; } + constexpr tile& operator[](std::size_t i) { return tiles[i]; } + constexpr const tile& operator[](std::size_t i) const { return tiles[i]; } + + template + requires std::invocable + constexpr inline void foreach_tile(F&& fun) { foreach_tile_(std::forward(fun)); } + + template + requires std::invocable + constexpr inline void foreach_tile(F&& fun) const { foreach_tile_(std::forward(fun)); } + +private: + template + constexpr void foreach_tile_(F&& fun); + + std::array tiles = {}; +}; + +template +constexpr void chunk::foreach_tile_(F&& fun) +{ + constexpr auto N = TILE_MAX_DIM; + std::size_t k = 0; + for (std::size_t j = 0; j < N; j++) + for (std::size_t i = 0; i < N; i++, k++) + fun(const_cast(*this).tiles[k], k, + local_coords{(std::uint8_t)i, (std::uint8_t)j}); +} + +#if 0 +struct chunk_coords final { + std::int16_t x = 0, y = 0; + constexpr std::size_t to_index() const noexcept; + + static constexpr std::size_t max_bits = sizeof(chunk_coords::x)*8 * 3 / 4; + static_assert(max_bits*4/3/8 == sizeof(decltype(chunk_coords::x))); +}; +#endif + +#if 0 +struct global_coords final { + std::uint32_t x = 0, y = 0; + constexpr global_coords() noexcept = default; + constexpr global_coords(decltype(x) x, decltype(y) y) noexcept : x{x}, y{y} {} + constexpr global_coords(chunk_coords c, local_coords tile) noexcept; +}; +#endif + +} // namespace Magnum::Examples diff --git a/src/floor-mesh.cpp b/src/floor-mesh.cpp new file mode 100644 index 00000000..7156661e --- /dev/null +++ b/src/floor-mesh.cpp @@ -0,0 +1,72 @@ +#include "floor-mesh.hpp" +#include "shaders/tile-shader.hpp" +#include "tile.hpp" +#include "chunk.hpp" +#include "tile-atlas.hpp" +#include + +namespace Magnum::Examples { + +constexpr auto quad_index_count = 6; + +floor_mesh::floor_mesh() +{ + _mesh.setCount((int)(quad_index_count * TILE_COUNT)) + .addVertexBuffer(_positions_buffer, 0, tile_shader::Position{}) + .addVertexBuffer(_vertex_buffer, 0, tile_shader::TextureCoordinates{}) + .setIndexBuffer(_index_buffer, 0, GL::MeshIndexType::UnsignedShort); +} + +void floor_mesh::set_tile(quad_data& data, tile& x) +{ + CORRADE_INTERNAL_ASSERT(x.ground_image); + + auto texcoords = x.ground_image.atlas->texcoords_for_id(x.ground_image.variant); + for (size_t i = 0; i < 4; i++) + data[i] = { texcoords[i] }; +} + +void floor_mesh::draw(tile_shader& shader, chunk& c) +{ + std::array data; + c.foreach_tile([&](tile& x, std::size_t idx, local_coords) { + set_tile(data[idx], x); + }); + _vertex_buffer.setSubData(0, data); + Magnum::GL::MeshView mesh{_mesh}; + mesh.setCount(quad_index_count); + const tile_atlas* last_tile_atlas = nullptr; + c.foreach_tile([&](tile& x, std::size_t i, local_coords) { + mesh.setIndexRange((int)(i*quad_index_count), 0, quad_index_count*TILE_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); + }); +} + +std::array, TILE_COUNT> floor_mesh::make_index_array() +{ + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init) + std::array, TILE_COUNT> array; + for (std::size_t i = 0; i < std::size(array); i++) + array[i] = tile_atlas::indices(i); + return array; +} + +std::array, TILE_COUNT> floor_mesh::make_position_array() +{ + std::array, TILE_COUNT> array; + constexpr float X = TILE_SIZE[0], Y = TILE_SIZE[1]; + for (std::size_t j = 0, k = 0; j < TILE_MAX_DIM; j++) + for (std::size_t i = 0; i < TILE_MAX_DIM; i++, k++) + { + Vector3 center {(float)(X*i), (float)(Y*j), 0}; + array[k] = { tile_atlas::floor_quad(center, {X, Y}) }; + } + return array; +} + +} // namespace Magnum::Examples diff --git a/src/floor-mesh.hpp b/src/floor-mesh.hpp new file mode 100644 index 00000000..41351fd9 --- /dev/null +++ b/src/floor-mesh.hpp @@ -0,0 +1,37 @@ +#pragma once +#include "tile.hpp" +#include +#include +#include +#include +#include +#include + +namespace Magnum::Examples { + +struct tile_shader; +struct chunk; + +struct floor_mesh final +{ + floor_mesh(); + floor_mesh(floor_mesh&&) = delete; + floor_mesh(const floor_mesh&) = delete; + + void draw(tile_shader& shader, chunk& c); + +private: + struct vertex_data final { Vector2 texcoords; }; + using quad_data = std::array; + + static std::array, TILE_COUNT> make_index_array(); + static std::array, TILE_COUNT> make_position_array(); + + GL::Mesh _mesh; + GL::Buffer _vertex_buffer{std::array{}, Magnum::GL::BufferUsage::DynamicDraw}, + _index_buffer{make_index_array()}, _positions_buffer{make_position_array()}; + + static void set_tile(quad_data& data, tile& x); +}; + +} // namespace Magnum::Examples diff --git a/src/loader.cpp b/src/loader.cpp new file mode 100644 index 00000000..f6219350 --- /dev/null +++ b/src/loader.cpp @@ -0,0 +1,6 @@ +#include "loader.hpp" + +namespace Magnum::Examples { +loader_::loader_() = default; +loader_::~loader_() = default; +} // namespace Magnum::Examples diff --git a/src/loader.hpp b/src/loader.hpp new file mode 100644 index 00000000..49299bb6 --- /dev/null +++ b/src/loader.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include +#include + +#include +#include +#include + +namespace Magnum::Examples { + +struct tile_atlas; + +struct loader_ +{ + virtual std::string shader(Containers::StringView filename) = 0; + virtual Trade::ImageData2D tile_texture(Containers::StringView filename) = 0; + virtual std::shared_ptr tile_atlas(Containers::StringView filename, Vector2ui size) = 0; + static void destroy(); + + loader_(const loader_&) = delete; + loader_& operator=(const loader_&) = delete; + + virtual ~loader_(); + +protected: + loader_(); +}; + +extern loader_& loader; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) + +} // namespace Magnum::Examples diff --git a/src/tile-atlas.cpp b/src/tile-atlas.cpp new file mode 100644 index 00000000..d5d56cce --- /dev/null +++ b/src/tile-atlas.cpp @@ -0,0 +1,39 @@ +#include "tile-atlas.hpp" +#include +#include +#include + +namespace Magnum::Examples { + +tile_atlas::tile_atlas(Containers::StringView name, const ImageView2D& image, Vector2ui dims) : + name_{name}, + size_{image.size()}, + dims_{dims} +{ + CORRADE_INTERNAL_ASSERT(dims_[0] > 0 && dims_[1] > 0); + CORRADE_INTERNAL_ASSERT(size_ % dims_ == Vector2ui{}); + CORRADE_INTERNAL_ASSERT(dims_.product() < 256); + tex_.setWrapping(GL::SamplerWrapping::ClampToBorder) + .setMagnificationFilter(GL::SamplerFilter::Linear) + .setMinificationFilter(GL::SamplerFilter::Linear) + .setMaxAnisotropy(0) + .setStorage(GL::textureFormat(image.format()), image.size()) + .setSubImage({}, image); +} + +std::array tile_atlas::texcoords_for_id(std::size_t id_) const +{ + const auto sz = size_/dims_; + ASSERT(id_ < sz.product()); + const Vector2ui id = { (unsigned)id_ % dims_[0], (unsigned)id_ / dims_[0] }; + const Vector2 p0(id * sz), p1(sz); + const auto x0 = p0.x(), x1 = p1.x(), y0 = p0.y(), y1 = p1.y(); + return {{ + { x0+x1, y0+y1 }, // bottom right + { x0+x1, y0 }, // top right + { x0, y0+y1 }, // bottom left + { x0, y0 } // top left + }}; +} + +} // namespace Magnum::Examples diff --git a/src/tile-atlas.hpp b/src/tile-atlas.hpp new file mode 100644 index 00000000..b32a70d8 --- /dev/null +++ b/src/tile-atlas.hpp @@ -0,0 +1,74 @@ +#pragma once +#include "compat/assert.hpp" +#include +#include +#include +#include + +namespace Magnum::Examples { + +struct tile_atlas final +{ + using quad = std::array; + + tile_atlas(Containers::StringView name, const ImageView2D& img, Vector2ui dimensions); + + std::array texcoords_for_id(std::size_t id) const; + static constexpr quad floor_quad(Vector3 center, Vector2 size); + static constexpr quad wall_quad_N(Vector3 center, Vector3 size); + static constexpr quad wall_quad_W(Vector3 center, Vector3 size); + static constexpr std::array indices(std::size_t N); + Vector2ui pixel_size() const { return size_; } + Vector2ui num_tiles() const { return dims_; } + GL::RectangleTexture& texture() { return tex_; } + Containers::StringView name() const { return name_; } + +private: + GL::RectangleTexture tex_; + std::string name_; + Vector2ui size_, dims_; +}; + +constexpr std::array tile_atlas::indices(std::size_t N) +{ + using u16 = UnsignedShort; + return { /* 3--1 1 */ + (u16)(0+N*4), (u16)(1+N*4), (u16)(2+N*4), /* | / /| */ + (u16)(2+N*4), (u16)(1+N*4), (u16)(3+N*4), /* |/ / | */ + }; /* 2 2--0 */ +} + +constexpr tile_atlas::quad tile_atlas::floor_quad(const Vector3 center, const Vector2 size) +{ + float x = size[0]*.5f, y = size[1]*.5f; + return {{ + { x + center[0], -y + center[1], center[2]}, + { x + center[0], y + center[1], center[2]}, + {-x + center[0], -y + center[1], center[2]}, + {-x + center[0], y + center[1], center[2]}, + }}; +} + +constexpr tile_atlas::quad tile_atlas::wall_quad_W(const Vector3 center, const Vector3 size) +{ + float x = size[0]*.5f, y = size[1]*.5f, z = size[2]; + return {{ + {-x + center[0], y + center[1], center[2] }, + {-x + center[0], y + center[1], z + center[2] }, + {-x + center[0], -y + center[1], center[2] }, + {-x + center[0], -y + center[1], z + center[2] }, + }}; +} + +constexpr tile_atlas::quad tile_atlas::wall_quad_N(const Vector3 center, const Vector3 size) +{ + float x = size[0]*.5f, y = size[1]*.5f, z = size[2]; + return {{ + { x + center[0], -y + center[1], center[2] }, + { x + center[0], -y + center[1], z + center[2] }, + {-x + center[0], -y + center[1], center[2] }, + {-x + center[0], -y + center[1], z + center[2] }, + }}; +} + +} // namespace Magnum::Examples diff --git a/src/tile.cpp b/src/tile.cpp new file mode 100644 index 00000000..41d11067 --- /dev/null +++ b/src/tile.cpp @@ -0,0 +1,11 @@ +#include "tile.hpp" +#include "tile-atlas.hpp" + +namespace Magnum::Examples { + +local_coords::local_coords(std::size_t x, std::size_t y) : x{(std::uint8_t)x}, y{(std::uint8_t)y} +{ + CORRADE_INTERNAL_ASSERT(x <= 0xff && y <= 0xff); +} + +} // namespace Magnum::Examples diff --git a/src/tile.hpp b/src/tile.hpp new file mode 100644 index 00000000..261c50ee --- /dev/null +++ b/src/tile.hpp @@ -0,0 +1,40 @@ +#pragma once +#include +#include +#include +#include +#include + +namespace Magnum::Examples { + +struct tile_atlas; +constexpr inline Vector3 TILE_SIZE = { 64, 64, 64 }; +constexpr inline std::size_t TILE_MAX_DIM = 16; +constexpr inline std::size_t TILE_COUNT = TILE_MAX_DIM*TILE_MAX_DIM; + +struct tile_image final +{ + std::shared_ptr atlas; + std::uint8_t variant = 0xff; + + explicit operator bool() const noexcept { return !!atlas; } +}; + +struct tile final +{ + enum class pass_mode : std::uint8_t { pass_blocked, pass_ok, pass_shoot_through, }; + using enum pass_mode; + + tile_image ground_image, wall_west, wall_north; + pass_mode passability = pass_shoot_through; +}; + +struct local_coords final { + std::uint8_t x = 0, y = 0; + constexpr local_coords() = default; + local_coords(std::size_t x, std::size_t y); + constexpr local_coords(std::uint8_t x, std::uint8_t y) : x{x}, y{y} {} + constexpr std::size_t to_index() const { return y*TILE_MAX_DIM + x; } +}; + +} //namespace Magnum::Examples diff --git a/src/wall-mesh.cpp b/src/wall-mesh.cpp new file mode 100644 index 00000000..ee998e63 --- /dev/null +++ b/src/wall-mesh.cpp @@ -0,0 +1,82 @@ +#include "wall-mesh.hpp" +#include "tile-atlas.hpp" +#include "shaders/tile-shader.hpp" +#include "chunk.hpp" +#include +#include + +namespace Magnum::Examples { + +constexpr auto quad_index_count = 6; + +wall_mesh::wall_mesh() +{ + _mesh.setCount((int)(quad_index_count * COUNT)) + .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, texture_array& textures, 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] }; + textures[pos] = &img.atlas->texture(); + } +} + +void wall_mesh::maybe_add_tile(vertex_array& data, texture_array& textures, 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, textures, pos, wall, tile_atlas::wall_quad_N(center, size)); + if (auto& wall = x.wall_west; wall.atlas) + add_wall(data, textures, pos, wall, tile_atlas::wall_quad_W(center, size)); +} + +void wall_mesh::draw(tile_shader& shader, chunk& c) +{ + texture_array textures = {}; + std::size_t pos = 0; + { + vertex_array data; + c.foreach_tile([&](tile& x, std::size_t, local_coords pt) { + maybe_add_tile(data, textures, pos, x, pt); + }); + _vertex_buffer.setSubData(0, Containers::arrayView(data.data(), pos)); + } + + const GL::RectangleTexture* last_texture = nullptr; + Magnum::GL::MeshView mesh{_mesh}; + for (std::size_t i = 0; i < pos; i++) + { + auto* const tex = textures[i]; + CORRADE_INTERNAL_ASSERT(tex != nullptr); + mesh.setCount(quad_index_count); + mesh.setIndexRange((int)(i*quad_index_count), 0, quad_index_count*COUNT - 1); + if (tex != last_texture) + tex->bind(0); + last_texture = tex; + shader.draw(mesh); + } +} + +std::array, wall_mesh::COUNT> wall_mesh::make_index_array() +{ + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init) + std::array, COUNT> array; + + for (std::size_t i = 0; i < std::size(array); i++) + array[i] = tile_atlas::indices(i); + return array; +} + +} // namespace Magnum::Examples diff --git a/src/wall-mesh.hpp b/src/wall-mesh.hpp new file mode 100644 index 00000000..ce1ff30a --- /dev/null +++ b/src/wall-mesh.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include "tile.hpp" +#include +#include +#include +#include +#include +#include + +namespace Magnum::Examples { + +struct tile_shader; +struct chunk; + +struct wall_mesh final +{ + wall_mesh(); + void draw(tile_shader& shader, chunk& c); + +private: + static constexpr auto COUNT = TILE_MAX_DIM*2 * TILE_MAX_DIM*2; + + using texcoords_array = std::array; + using position_array = std::array; + + struct vertex final { + typename texcoords_array::value_type texcoords; + typename position_array::value_type position; + }; + + using quad = std::array; + using vertex_array = std::array; + using texture_array = std::array; + + static void maybe_add_tile(vertex_array& data, texture_array& textures, std::size_t& pos, + tile& x, local_coords pt); + static void add_wall(vertex_array& data, texture_array& textures, std::size_t& pos, + tile_image& img, const position_array& positions); + + GL::Mesh _mesh; + GL::Buffer _vertex_buffer{vertex_array{}, Magnum::GL::BufferUsage::DynamicDraw}, + _index_buffer{make_index_array(), Magnum::GL::BufferUsage::StaticDraw}; + static std::array, COUNT> make_index_array(); +}; + +} // namespace Magnum::Examples diff --git a/tile-atlas.cpp b/tile-atlas.cpp deleted file mode 100644 index d5d56cce..00000000 --- a/tile-atlas.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "tile-atlas.hpp" -#include -#include -#include - -namespace Magnum::Examples { - -tile_atlas::tile_atlas(Containers::StringView name, const ImageView2D& image, Vector2ui dims) : - name_{name}, - size_{image.size()}, - dims_{dims} -{ - CORRADE_INTERNAL_ASSERT(dims_[0] > 0 && dims_[1] > 0); - CORRADE_INTERNAL_ASSERT(size_ % dims_ == Vector2ui{}); - CORRADE_INTERNAL_ASSERT(dims_.product() < 256); - tex_.setWrapping(GL::SamplerWrapping::ClampToBorder) - .setMagnificationFilter(GL::SamplerFilter::Linear) - .setMinificationFilter(GL::SamplerFilter::Linear) - .setMaxAnisotropy(0) - .setStorage(GL::textureFormat(image.format()), image.size()) - .setSubImage({}, image); -} - -std::array tile_atlas::texcoords_for_id(std::size_t id_) const -{ - const auto sz = size_/dims_; - ASSERT(id_ < sz.product()); - const Vector2ui id = { (unsigned)id_ % dims_[0], (unsigned)id_ / dims_[0] }; - const Vector2 p0(id * sz), p1(sz); - const auto x0 = p0.x(), x1 = p1.x(), y0 = p0.y(), y1 = p1.y(); - return {{ - { x0+x1, y0+y1 }, // bottom right - { x0+x1, y0 }, // top right - { x0, y0+y1 }, // bottom left - { x0, y0 } // top left - }}; -} - -} // namespace Magnum::Examples diff --git a/tile-atlas.hpp b/tile-atlas.hpp deleted file mode 100644 index b32a70d8..00000000 --- a/tile-atlas.hpp +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once -#include "compat/assert.hpp" -#include -#include -#include -#include - -namespace Magnum::Examples { - -struct tile_atlas final -{ - using quad = std::array; - - tile_atlas(Containers::StringView name, const ImageView2D& img, Vector2ui dimensions); - - std::array texcoords_for_id(std::size_t id) const; - static constexpr quad floor_quad(Vector3 center, Vector2 size); - static constexpr quad wall_quad_N(Vector3 center, Vector3 size); - static constexpr quad wall_quad_W(Vector3 center, Vector3 size); - static constexpr std::array indices(std::size_t N); - Vector2ui pixel_size() const { return size_; } - Vector2ui num_tiles() const { return dims_; } - GL::RectangleTexture& texture() { return tex_; } - Containers::StringView name() const { return name_; } - -private: - GL::RectangleTexture tex_; - std::string name_; - Vector2ui size_, dims_; -}; - -constexpr std::array tile_atlas::indices(std::size_t N) -{ - using u16 = UnsignedShort; - return { /* 3--1 1 */ - (u16)(0+N*4), (u16)(1+N*4), (u16)(2+N*4), /* | / /| */ - (u16)(2+N*4), (u16)(1+N*4), (u16)(3+N*4), /* |/ / | */ - }; /* 2 2--0 */ -} - -constexpr tile_atlas::quad tile_atlas::floor_quad(const Vector3 center, const Vector2 size) -{ - float x = size[0]*.5f, y = size[1]*.5f; - return {{ - { x + center[0], -y + center[1], center[2]}, - { x + center[0], y + center[1], center[2]}, - {-x + center[0], -y + center[1], center[2]}, - {-x + center[0], y + center[1], center[2]}, - }}; -} - -constexpr tile_atlas::quad tile_atlas::wall_quad_W(const Vector3 center, const Vector3 size) -{ - float x = size[0]*.5f, y = size[1]*.5f, z = size[2]; - return {{ - {-x + center[0], y + center[1], center[2] }, - {-x + center[0], y + center[1], z + center[2] }, - {-x + center[0], -y + center[1], center[2] }, - {-x + center[0], -y + center[1], z + center[2] }, - }}; -} - -constexpr tile_atlas::quad tile_atlas::wall_quad_N(const Vector3 center, const Vector3 size) -{ - float x = size[0]*.5f, y = size[1]*.5f, z = size[2]; - return {{ - { x + center[0], -y + center[1], center[2] }, - { x + center[0], -y + center[1], z + center[2] }, - {-x + center[0], -y + center[1], center[2] }, - {-x + center[0], -y + center[1], z + center[2] }, - }}; -} - -} // namespace Magnum::Examples diff --git a/tile.cpp b/tile.cpp deleted file mode 100644 index 41d11067..00000000 --- a/tile.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "tile.hpp" -#include "tile-atlas.hpp" - -namespace Magnum::Examples { - -local_coords::local_coords(std::size_t x, std::size_t y) : x{(std::uint8_t)x}, y{(std::uint8_t)y} -{ - CORRADE_INTERNAL_ASSERT(x <= 0xff && y <= 0xff); -} - -} // namespace Magnum::Examples diff --git a/tile.hpp b/tile.hpp deleted file mode 100644 index 261c50ee..00000000 --- a/tile.hpp +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include - -namespace Magnum::Examples { - -struct tile_atlas; -constexpr inline Vector3 TILE_SIZE = { 64, 64, 64 }; -constexpr inline std::size_t TILE_MAX_DIM = 16; -constexpr inline std::size_t TILE_COUNT = TILE_MAX_DIM*TILE_MAX_DIM; - -struct tile_image final -{ - std::shared_ptr atlas; - std::uint8_t variant = 0xff; - - explicit operator bool() const noexcept { return !!atlas; } -}; - -struct tile final -{ - enum class pass_mode : std::uint8_t { pass_blocked, pass_ok, pass_shoot_through, }; - using enum pass_mode; - - tile_image ground_image, wall_west, wall_north; - pass_mode passability = pass_shoot_through; -}; - -struct local_coords final { - std::uint8_t x = 0, y = 0; - constexpr local_coords() = default; - local_coords(std::size_t x, std::size_t y); - constexpr local_coords(std::uint8_t x, std::uint8_t y) : x{x}, y{y} {} - constexpr std::size_t to_index() const { return y*TILE_MAX_DIM + x; } -}; - -} //namespace Magnum::Examples diff --git a/wall-mesh.cpp b/wall-mesh.cpp deleted file mode 100644 index ee998e63..00000000 --- a/wall-mesh.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "wall-mesh.hpp" -#include "tile-atlas.hpp" -#include "shaders/tile-shader.hpp" -#include "chunk.hpp" -#include -#include - -namespace Magnum::Examples { - -constexpr auto quad_index_count = 6; - -wall_mesh::wall_mesh() -{ - _mesh.setCount((int)(quad_index_count * COUNT)) - .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, texture_array& textures, 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] }; - textures[pos] = &img.atlas->texture(); - } -} - -void wall_mesh::maybe_add_tile(vertex_array& data, texture_array& textures, 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, textures, pos, wall, tile_atlas::wall_quad_N(center, size)); - if (auto& wall = x.wall_west; wall.atlas) - add_wall(data, textures, pos, wall, tile_atlas::wall_quad_W(center, size)); -} - -void wall_mesh::draw(tile_shader& shader, chunk& c) -{ - texture_array textures = {}; - std::size_t pos = 0; - { - vertex_array data; - c.foreach_tile([&](tile& x, std::size_t, local_coords pt) { - maybe_add_tile(data, textures, pos, x, pt); - }); - _vertex_buffer.setSubData(0, Containers::arrayView(data.data(), pos)); - } - - const GL::RectangleTexture* last_texture = nullptr; - Magnum::GL::MeshView mesh{_mesh}; - for (std::size_t i = 0; i < pos; i++) - { - auto* const tex = textures[i]; - CORRADE_INTERNAL_ASSERT(tex != nullptr); - mesh.setCount(quad_index_count); - mesh.setIndexRange((int)(i*quad_index_count), 0, quad_index_count*COUNT - 1); - if (tex != last_texture) - tex->bind(0); - last_texture = tex; - shader.draw(mesh); - } -} - -std::array, wall_mesh::COUNT> wall_mesh::make_index_array() -{ - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init) - std::array, COUNT> array; - - for (std::size_t i = 0; i < std::size(array); i++) - array[i] = tile_atlas::indices(i); - return array; -} - -} // namespace Magnum::Examples diff --git a/wall-mesh.hpp b/wall-mesh.hpp deleted file mode 100644 index ce1ff30a..00000000 --- a/wall-mesh.hpp +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include "tile.hpp" -#include -#include -#include -#include -#include -#include - -namespace Magnum::Examples { - -struct tile_shader; -struct chunk; - -struct wall_mesh final -{ - wall_mesh(); - void draw(tile_shader& shader, chunk& c); - -private: - static constexpr auto COUNT = TILE_MAX_DIM*2 * TILE_MAX_DIM*2; - - using texcoords_array = std::array; - using position_array = std::array; - - struct vertex final { - typename texcoords_array::value_type texcoords; - typename position_array::value_type position; - }; - - using quad = std::array; - using vertex_array = std::array; - using texture_array = std::array; - - static void maybe_add_tile(vertex_array& data, texture_array& textures, std::size_t& pos, - tile& x, local_coords pt); - static void add_wall(vertex_array& data, texture_array& textures, std::size_t& pos, - tile_image& img, const position_array& positions); - - GL::Mesh _mesh; - GL::Buffer _vertex_buffer{vertex_array{}, Magnum::GL::BufferUsage::DynamicDraw}, - _index_buffer{make_index_array(), Magnum::GL::BufferUsage::StaticDraw}; - static std::array, COUNT> make_index_array(); -}; - -} // namespace Magnum::Examples -- cgit v1.2.3