From 445caf6184cafbce361670ea6028ff76317976bc Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sun, 2 Oct 2022 15:29:41 +0200 Subject: a --- CMakeLists.txt | 2 +- anim-crop-tool/main.cpp | 3 +- anim/serialize.hpp | 2 -- chunk.hpp | 32 +++-------------- compat/assert.hpp | 70 ++++++++++++++++++++++++++++++++++++ compat/defs.hpp | 18 ++++++++++ compat/sysexits.hpp | 11 ++++++ defs.hpp | 94 ------------------------------------------------- floor-mesh.cpp | 13 ++++--- floor-mesh.hpp | 1 - loader-impl.cpp | 2 +- main.cpp | 36 ++----------------- shaders/tile-shader.cpp | 54 ++++++++++++++++++++++++++++ shaders/tile-shader.hpp | 41 +++++++++++++++++++++ tile-atlas.cpp | 1 - tile-shader.cpp | 60 ------------------------------- tile-shader.hpp | 35 ------------------ tile.hpp | 1 - wall-mesh.cpp | 5 +++ wall-mesh.hpp | 5 +++ 20 files changed, 223 insertions(+), 263 deletions(-) create mode 100644 compat/assert.hpp create mode 100644 compat/defs.hpp create mode 100644 compat/sysexits.hpp delete mode 100644 defs.hpp create mode 100644 shaders/tile-shader.cpp create mode 100644 shaders/tile-shader.hpp delete mode 100644 tile-shader.cpp delete mode 100644 tile-shader.hpp create mode 100644 wall-mesh.cpp create mode 100644 wall-mesh.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 5bb59495..eb77c3e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,7 +62,7 @@ if(NOT BOOTSTRAP_DEPENDS) add_subdirectory(tile) corrade_add_resource(game_RESOURCES resources.conf) - file(GLOB sources "*.cpp" CONFIGURE_ARGS) + file(GLOB sources "*.cpp" "shaders/*.cpp" CONFIGURE_ARGS) add_executable(${PROJECT_NAME} WIN32 "${sources}" "${game_RESOURCES}") target_link_libraries(${PROJECT_NAME} PRIVATE diff --git a/anim-crop-tool/main.cpp b/anim-crop-tool/main.cpp index 42d54baa..ff4c9e72 100644 --- a/anim-crop-tool/main.cpp +++ b/anim-crop-tool/main.cpp @@ -1,8 +1,9 @@ #undef NDEBUG -#include "defs.hpp" #include "atlas.hpp" #include "anim/serialize.hpp" +#include "compat/defs.hpp" +#include "compat/sysexits.hpp" #include #include diff --git a/anim/serialize.hpp b/anim/serialize.hpp index 49641fb5..3e039a96 100644 --- a/anim/serialize.hpp +++ b/anim/serialize.hpp @@ -1,7 +1,5 @@ #pragma once -#include "defs.hpp" - #include #include #include diff --git a/chunk.hpp b/chunk.hpp index 7bfea8d7..829ee0d3 100644 --- a/chunk.hpp +++ b/chunk.hpp @@ -7,14 +7,10 @@ namespace Magnum::Examples { struct chunk final { - //using index_type = std::common_type_t; - //using tile_index_array_type = std::array; - //static constexpr inline local_coords center = { (index_type)(N/2), (index_type)(N/2) }; - - constexpr tile& operator[](local_coords xy); - constexpr const tile& operator[](local_coords xy) const; - constexpr tile& operator[](std::size_t i); - constexpr const tile& operator[](std::size_t i) const; + 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 @@ -31,26 +27,6 @@ private: std::array tiles = {}; }; -constexpr tile& chunk::operator[](std::size_t i) { - if (i >= TILE_COUNT) - throw OUT_OF_RANGE(i, 0, TILE_COUNT); - return tiles[i]; -} - -constexpr const tile& chunk::operator[](std::size_t i) const { - return const_cast(*this).operator[](i); -} - -constexpr const tile& chunk::operator[](local_coords xy) const { - return const_cast(*this).operator[](xy); -} - -constexpr tile& chunk::operator[](local_coords xy) -{ - auto idx = xy.to_index(); - return operator[](idx); -} - template constexpr void chunk::foreach_tile_(F&& fun) { diff --git a/compat/assert.hpp b/compat/assert.hpp new file mode 100644 index 00000000..b2022231 --- /dev/null +++ b/compat/assert.hpp @@ -0,0 +1,70 @@ +#pragma once +#include "defs.hpp" +#include + +namespace Magnum::Examples { + +struct exception { + const char* file = nullptr; + const char* function = nullptr; + int line = -1; +}; + +struct assertion_failure final : exception +{ + char msg[128 - sizeof(int) - sizeof(char*)]; +}; + +struct out_of_range final : exception { + ssize_t value = 0; + ssize_t min = std::numeric_limits::min(); + ssize_t max = std::numeric_limits::max(); +}; + +struct key_error final : exception { + ssize_t value = 0; +}; + +#define KEY_ERROR(value) \ + ::Magnum::Examples::key_error{{__FILE__, FUNCTION_NAME, __LINE__}, (value)} + +#define OUT_OF_RANGE(value, min, max) \ + ::Magnum::Examples::out_of_range{ \ + {__FILE__, FUNCTION_NAME, __LINE__}, \ + ::Magnum::Examples::ssize_t((value)), \ + ::Magnum::Examples::ssize_t((min)), \ + ::Magnum::Examples::ssize_t((max)) \ + } + +#define ABORT_WITH(exc_type, ...) ([&]() { \ + exc_type _e; \ + _e.line = __LINE__; \ + _e.file = __FILE__; \ + _e.function = FUNCTION_NAME; \ + std::snprintf(_e.msg, sizeof(_e.msg), __VA_ARGS__); \ + throw _e;/*NOLINT(misc-throw-by-value-catch-by-reference)*/ \ +}()) + +#define ABORT(...) \ + ABORT_WITH(::Magnum::Examples::assertion_failure, __VA_ARGS__) + +#define ASSERT(expr) \ + do { \ + if (!(expr)) \ + ABORT("assertion failed: '%s' in %s:%d", \ + #expr, __FILE__, __LINE__); \ + } while(false) + +#define GAME_DEBUG_OUT(pfx, ...) ([&]() { \ + if constexpr (sizeof((pfx)) > 1) \ + std::fputs((pfx), stderr); \ + std::fprintf(stderr, __VA_ARGS__); \ + std::fputs("\n", stderr); \ + std::fflush(stderr); \ +}()) + +#define WARN(...) GAME_DEBUG_OUT("warning: ", __VA_ARGS__) +#define ERR(...) GAME_DEBUG_OUT("error: ", __VA_ARGS__) +#define DEBUG(...) GAME_DEBUG_OUT("", __VA_ARGS__) + +} // namespace Magnum::Examples diff --git a/compat/defs.hpp b/compat/defs.hpp new file mode 100644 index 00000000..cc238022 --- /dev/null +++ b/compat/defs.hpp @@ -0,0 +1,18 @@ +#pragma once +#include +#include + +namespace Magnum::Examples { + +using size_t = std::size_t; +using ssize_t = std::make_signed_t; + +} // namespace Magnum::Examples + +#ifdef _MSC_VER +# define FUNCTION_NAME __FUNCSIG__ +#else +# define FUNCTION_NAME __PRETTY_FUNCTION__ +#endif + +#define progn(...) [&]{__VA_ARGS__;}() diff --git a/compat/sysexits.hpp b/compat/sysexits.hpp new file mode 100644 index 00000000..a7a9c317 --- /dev/null +++ b/compat/sysexits.hpp @@ -0,0 +1,11 @@ +#pragma once +#ifdef _WIN32 +# define EX_OK 0 /* successful termination */ +# define EX_USAGE 64 /* command line usage error */ +# define EX_DATAERR 65 /* data format error */ +# define EX_SOFTWARE 70 /* internal software error */ +# define EX_CANTCREAT 73 /* can't create (user) output file */ +# define EX_IOERR 74 /* input/output error */ +#else +# include +#endif diff --git a/defs.hpp b/defs.hpp deleted file mode 100644 index 758345f9..00000000 --- a/defs.hpp +++ /dev/null @@ -1,94 +0,0 @@ -#pragma once -#include -#include -#include -#include - -#ifdef _MSC_VER -# define FUNCTION_NAME __FUNCSIG__ -#else -# define FUNCTION_NAME __PRETTY_FUNCTION__ -#endif - -#ifdef _WIN32 -# define EX_OK 0 /* successful termination */ -# define EX_USAGE 64 /* command line usage error */ -# define EX_DATAERR 65 /* data format error */ -# define EX_SOFTWARE 70 /* internal software error */ -# define EX_CANTCREAT 73 /* can't create (user) output file */ -# define EX_IOERR 74 /* input/output error */ -#else -# include -#endif - -namespace Magnum::Examples { - -using size_t = std::size_t; -using ssize_t = std::make_signed_t; - -struct exception { - const char* file = nullptr; - const char* function = nullptr; - int line = -1; -}; - -struct assertion_failure final : exception -{ - char msg[128 - sizeof(int) - sizeof(char*)]; -}; - -struct out_of_range final : exception { - ssize_t value = 0; - ssize_t min = std::numeric_limits::min(); - ssize_t max = std::numeric_limits::max(); -}; - -struct key_error final : exception { - ssize_t value = 0; -}; - -} // namespace Magnum::Examples - -#define KEY_ERROR(value) \ - ::Magnum::Examples::key_error{{__FILE__, FUNCTION_NAME, __LINE__}, (value)} - -#define OUT_OF_RANGE(value, min, max) \ - ::Magnum::Examples::out_of_range{ \ - {__FILE__, FUNCTION_NAME, __LINE__}, \ - ::Magnum::Examples::ssize_t((value)), \ - ::Magnum::Examples::ssize_t((min)), \ - ::Magnum::Examples::ssize_t((max)) \ - } - -#define ABORT_WITH(exc_type, ...) ([&]() { \ - exc_type _e; \ - _e.line = __LINE__; \ - _e.file = __FILE__; \ - _e.function = FUNCTION_NAME; \ - std::snprintf(_e.msg, sizeof(_e.msg), __VA_ARGS__); \ - throw _e;/*NOLINT(misc-throw-by-value-catch-by-reference)*/ \ -}()) - -#define ABORT(...) \ - ABORT_WITH(::Magnum::Examples::assertion_failure, __VA_ARGS__) - -#define ASSERT(expr) \ - do { \ - if (!(expr)) \ - ABORT("assertion failed: '%s' in %s:%d", \ - #expr, __FILE__, __LINE__); \ - } while(false) - -#define GAME_DEBUG_OUT(pfx, ...) ([&]() { \ - if constexpr (sizeof((pfx)) > 1) \ - std::fputs((pfx), stderr); \ - std::fprintf(stderr, __VA_ARGS__); \ - std::fputs("\n", stderr); \ - std::fflush(stderr); \ -}()) - -#define WARN(...) GAME_DEBUG_OUT("warning: ", __VA_ARGS__) -#define ERR(...) GAME_DEBUG_OUT("error: ", __VA_ARGS__) -#define DEBUG(...) GAME_DEBUG_OUT("", __VA_ARGS__) - -#define progn(...) [&]{__VA_ARGS__;}() diff --git a/floor-mesh.cpp b/floor-mesh.cpp index 32e5bb8e..e9dd57b1 100644 --- a/floor-mesh.cpp +++ b/floor-mesh.cpp @@ -1,6 +1,6 @@ #include "floor-mesh.hpp" #include "tile-atlas.hpp" -#include "tile-shader.hpp" +#include "shaders/tile-shader.hpp" #include "tile.hpp" #include "chunk.hpp" #include @@ -19,7 +19,6 @@ void floor_mesh::set_tile(tile& x, const local_coords pt) { CORRADE_INTERNAL_ASSERT(x.ground_image); - constexpr float X = TILE_SIZE[0], Y = TILE_SIZE[1]; const auto idx = pt.to_index(); auto texcoords = x.ground_image.atlas->texcoords_for_id(x.ground_image.variant); for (std::size_t i = 0; i < 4; i++) @@ -31,14 +30,18 @@ void floor_mesh::draw(tile_shader& shader, chunk& c) c.foreach_tile([&](tile& x, std::size_t, local_coords pt) { set_tile(x, pt); }); - _vertex_buffer.setData(_vertex_data, Magnum::GL::BufferUsage::DynamicDraw); #if 1 Magnum::GL::MeshView mesh{ _mesh }; mesh.setCount(quad_index_count); + 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); - x.ground_image.atlas->texture().bind(0); + if (auto* atlas = x.ground_image.atlas.get(); atlas != last_tile_atlas) + { + atlas->texture().bind(0); + last_tile_atlas = atlas; + } shader.draw(mesh); }); #else @@ -52,7 +55,7 @@ static auto make_index_array() constexpr auto quad_index_count = std::tuple_size_v; std::array, TILE_COUNT> array; // NOLINT(cppcoreguidelines-pro-type-member-init) - for (std::size_t i = 0, k = 0; i < std::size(array); i++) + for (std::size_t i = 0; i < std::size(array); i++) array[i] = tile_atlas::indices(i); return array; } diff --git a/floor-mesh.hpp b/floor-mesh.hpp index 2dfdf5f3..7d7eff6f 100644 --- a/floor-mesh.hpp +++ b/floor-mesh.hpp @@ -1,5 +1,4 @@ #pragma once -#include "defs.hpp" #include "tile.hpp" #include "tile-atlas.hpp" #include diff --git a/loader-impl.cpp b/loader-impl.cpp index b761dca4..f2f38aac 100644 --- a/loader-impl.cpp +++ b/loader-impl.cpp @@ -1,6 +1,6 @@ -#include "defs.hpp" #include "loader.hpp" #include "tile-atlas.hpp" +#include "compat/assert.hpp" #include #include #include diff --git a/main.cpp b/main.cpp index e701faa7..c7586d7f 100644 --- a/main.cpp +++ b/main.cpp @@ -1,10 +1,10 @@ #include "tile-atlas.hpp" #include "loader.hpp" -#include "tile-shader.hpp" -#include "defs.hpp" +#include "shaders/tile-shader.hpp" #include "tile.hpp" #include "chunk.hpp" #include "floor-mesh.hpp" +#include "compat/defs.hpp" #include @@ -79,7 +79,7 @@ chunk app::make_test_chunk() chunk c; c.foreach_tile([&, this](tile& x, std::size_t k, local_coords) { //const auto& atlas = (pt.y*TILE_MAX_DIM+pt.x+1) % 2 == 0 ? floor1 : floor2; - const auto& atlas = floor2; + const auto& atlas = floor1; x.ground_image = { atlas, (std::uint8_t)(k % atlas->size()) }; }); return c; @@ -88,7 +88,6 @@ chunk app::make_test_chunk() void app::draw_chunk(chunk& c) { constexpr auto N = TILE_MAX_DIM; - constexpr float X = TILE_SIZE[0], Y = TILE_SIZE[1]; for (std::size_t j = 0, k = 0; j < N; j++) for (std::size_t i = 0; i < N; i++, k++) @@ -115,35 +114,6 @@ app::app(const Arguments& arguments): reset_camera_offset(); - { - vertices.clear(); - indices.clear(); - int k = 0; - constexpr auto N = TILE_MAX_DIM; - for (unsigned j = 0; j < N; j++) // TODO draw walls in correct order - for (unsigned i = 0; i < N; i++) - { - auto positions = floor1->floor_quad({(float)(X*i), (float)(Y*j), 0}, {X, Y}); - auto texcoords = floor1->texcoords_for_id(k % floor1->size()); - auto indices_ = floor1->indices(k); - - for (unsigned x = 0; x < 4; x++) - vertices.push_back({ positions[x], texcoords[x] }); - for (auto x : indices_) - indices.push_back(x); - k++; - } - - _mesh.setCount((int)indices.size()) - .addVertexBuffer(GL::Buffer{vertices}, 0, - tile_shader::Position{}, tile_shader::TextureCoordinates{}) - .addVertexBuffer(GL::Buffer{c.sampler_array()}, 0, tile_shader::TextureID{}) - .setIndexBuffer(GL::Buffer{indices}, 0, GL::MeshIndexType::UnsignedShort); - } - - vertices.clear(); - indices.clear(); - { constexpr auto N = TILE_MAX_DIM; Vector3 center{N/2.f*TILE_SIZE[0], N/2.f*TILE_SIZE[1], 0}; diff --git a/shaders/tile-shader.cpp b/shaders/tile-shader.cpp new file mode 100644 index 00000000..835f94a0 --- /dev/null +++ b/shaders/tile-shader.cpp @@ -0,0 +1,54 @@ +#include "shaders/tile-shader.hpp" +#include "loader.hpp" +#include +#include +#include +#include +#include +#include + +namespace Magnum::Examples { + +tile_shader::tile_shader() +{ + MAGNUM_ASSERT_GL_VERSION_SUPPORTED(GL::Version::GL460); + + GL::Shader vert{GL::Version::GL460, GL::Shader::Type::Vertex}; + GL::Shader frag{GL::Version::GL460, GL::Shader::Type::Fragment}; + + vert.addSource(loader.shader("shaders/tile-shader.vert")); + frag.addSource(loader.shader("shaders/tile-shader.frag")); + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif + CORRADE_INTERNAL_ASSERT_OUTPUT(GL::Shader::compile({vert, frag})); +#ifdef __clang__ +# pragma clang diagnostic pop +#endif + attachShaders({vert, frag}); + + CORRADE_INTERNAL_ASSERT_OUTPUT(link()); + + set_scale({640, 480}); + set_camera_offset({0, 0}); +} + +tile_shader& tile_shader::set_scale(const Vector2& scale) +{ + scale_ = scale; + setUniform(ScaleUniform, scale); + return *this; +} + +tile_shader& tile_shader::set_camera_offset(Vector2 camera_offset) +{ + CORRADE_INTERNAL_ASSERT(std::fabs(camera_offset[0]) <= std::scalbn(1.f, std::numeric_limits::digits)); + CORRADE_INTERNAL_ASSERT(std::fabs(camera_offset[1]) <= std::scalbn(1.f, std::numeric_limits::digits)); + camera_offset_ = camera_offset; + setUniform(OffsetUniform, camera_offset); + return *this; +} + +} // namespace Magnum::Examples diff --git a/shaders/tile-shader.hpp b/shaders/tile-shader.hpp new file mode 100644 index 00000000..a1975daf --- /dev/null +++ b/shaders/tile-shader.hpp @@ -0,0 +1,41 @@ +#pragma once +#include "tile-atlas.hpp" +#include +#include +#include +#include +#include +#include +#include + +struct tile_atlas; + +namespace Magnum::Examples { + +struct tile_shader : GL::AbstractShaderProgram +{ + typedef GL::Attribute<0, Vector3> Position; + typedef GL::Attribute<1, Vector2> TextureCoordinates; + + explicit tile_shader(); + + Vector2 scale() const { return scale_; } + tile_shader& set_scale(const Vector2& scale); + Vector2 camera_offset() const { return camera_offset_; } + tile_shader& set_camera_offset(Vector2 camera_offset); + + static inline Vector2 project(Vector3 pt); + +private: + Vector2 scale_, camera_offset_; + + enum { ScaleUniform = 0, OffsetUniform = 1, }; +}; + +Vector2 tile_shader::project(Vector3 pt) +{ + float x = pt[1], y = pt[0], z = pt[2]; + return { x-y, (x+y+z*2)*.75f }; +} + +} // namespace Magnum::Examples diff --git a/tile-atlas.cpp b/tile-atlas.cpp index bc2db18e..a716c376 100644 --- a/tile-atlas.cpp +++ b/tile-atlas.cpp @@ -1,5 +1,4 @@ #include "tile-atlas.hpp" -#include "defs.hpp" #include #include diff --git a/tile-shader.cpp b/tile-shader.cpp deleted file mode 100644 index 02470502..00000000 --- a/tile-shader.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "tile-shader.hpp" -#include "loader.hpp" -#include -#include -#include -#include -#include -#include - -namespace Magnum::Examples { - -tile_shader::tile_shader() -{ - MAGNUM_ASSERT_GL_VERSION_SUPPORTED(GL::Version::GL460); - - GL::Shader vert{GL::Version::GL460, GL::Shader::Type::Vertex}; - GL::Shader frag{GL::Version::GL460, GL::Shader::Type::Fragment}; - - vert.addSource(loader.shader("shaders/tile-shader.vert")); - frag.addSource(loader.shader("shaders/tile-shader.frag")); - -#ifdef __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wdeprecated-declarations" -#endif - CORRADE_INTERNAL_ASSERT_OUTPUT(GL::Shader::compile({vert, frag})); -#ifdef __clang__ -# pragma clang diagnostic pop -#endif - attachShaders({vert, frag}); - - CORRADE_INTERNAL_ASSERT_OUTPUT(link()); - - set_scale({640, 480}); - set_camera_offset({0, 0}); -} - -tile_shader& tile_shader::set_scale(const Vector2& scale) -{ - scale_ = scale; - setUniform(ScaleUniform, scale); - return *this; -} - -tile_shader& tile_shader::set_camera_offset(Vector2 camera_offset) -{ - CORRADE_INTERNAL_ASSERT(std::fabs(camera_offset[0]) <= std::scalbn(1.f, std::numeric_limits::digits)); - CORRADE_INTERNAL_ASSERT(std::fabs(camera_offset[1]) <= std::scalbn(1.f, std::numeric_limits::digits)); - camera_offset_ = camera_offset; - setUniform(OffsetUniform, camera_offset); - return *this; -} - -Vector2 tile_shader::project(Vector3 pt) -{ - float x = pt[1], y = pt[0], z = pt[2]; - return { x-y, (x+y+z*2)*.75f }; -} - -} // namespace Magnum::Examples diff --git a/tile-shader.hpp b/tile-shader.hpp deleted file mode 100644 index 1c2faabf..00000000 --- a/tile-shader.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once -#include "tile-atlas.hpp" -#include -#include -#include -#include -#include -#include -#include - -struct tile_atlas; - -namespace Magnum::Examples { - -struct tile_shader : GL::AbstractShaderProgram -{ - typedef GL::Attribute<0, Vector3> Position; - typedef GL::Attribute<1, Vector2> TextureCoordinates; - - explicit tile_shader(); - - Vector2 scale() const { return scale_; } - tile_shader& set_scale(const Vector2& scale); - Vector2 camera_offset() const { return camera_offset_; } - tile_shader& set_camera_offset(Vector2 camera_offset); - - static Vector2 project(Vector3 pt); - -private: - Vector2 scale_, camera_offset_; - - enum { ScaleUniform = 0, OffsetUniform = 1, }; -}; - -} // namespace Magnum::Examples diff --git a/tile.hpp b/tile.hpp index 39271cfb..9a5db20c 100644 --- a/tile.hpp +++ b/tile.hpp @@ -1,5 +1,4 @@ #pragma once -#include "defs.hpp" #include #include #include diff --git a/wall-mesh.cpp b/wall-mesh.cpp new file mode 100644 index 00000000..3dcbb38a --- /dev/null +++ b/wall-mesh.cpp @@ -0,0 +1,5 @@ +#include "wall-mesh.hpp" + +namespace Magnum::Examples { + +} // namespace Magnum::Examples diff --git a/wall-mesh.hpp b/wall-mesh.hpp new file mode 100644 index 00000000..b1f7be7e --- /dev/null +++ b/wall-mesh.hpp @@ -0,0 +1,5 @@ +#pragma once + +namespace Magnum::Examples { + +} // namespace Magnum::Examples -- cgit v1.2.3