diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | atlas.cpp | 15 | ||||
-rw-r--r-- | atlas.hpp | 3 | ||||
-rw-r--r-- | loader-impl.cpp | 6 | ||||
-rw-r--r-- | loader.hpp | 2 | ||||
-rw-r--r-- | main.cpp | 67 | ||||
-rw-r--r-- | shaders/tile-shader.vert | 2 | ||||
-rw-r--r-- | tile.hpp | 20 |
8 files changed, 68 insertions, 48 deletions
@@ -2,4 +2,5 @@ /.clang-tidy /.clang-format /.idea/ +/images/ /userconfig-*.cmake @@ -17,22 +17,23 @@ atlas_texture::atlas_texture(const Trade::ImageData2D& image, Vector2i dims) : tex_.setWrapping(GL::SamplerWrapping::ClampToEdge) .setMagnificationFilter(GL::SamplerFilter::Linear) .setMinificationFilter(GL::SamplerFilter::Linear) - .setStorage(MIPMAP_LEVEL, GL::textureFormat(image.format()), image.size()) + .setMaxAnisotropy(8) + .setStorage(6, GL::textureFormat(image.format()), image.size()) .setSubImage(0, {}, image); } std::array<Vector2, 4> atlas_texture::texcoords_for_id(int id_) const { CORRADE_INTERNAL_ASSERT(id_ >= 0 && id_ < dims_.product()); - constexpr Vector2i _1 = { 1, 1 }; Vector2i id = { id_ % dims_[0], id_ / dims_[0] }; auto p0 = Vector2(id * tile_size_) / Vector2(size_); - auto p1 = Vector2((id + _1) * tile_size_) / Vector2(size_); + auto p1 = (Vector2(Vector2i{1,1} * tile_size_) - Vector2{0.5f, 0.5f}) / Vector2(size_); + auto x0 = p0.x(), x1 = p1.x(), y0 = p0.y(), y1 = p1.y(); return {{ - { p1[0], p1[1] }, // bottom right - { p1[0], p0[1] }, // top right - { p0[0], p1[1] }, // bottom left - { p0[0], p0[1] } // top left + { x0+x1, y0+y1 }, // bottom right + { x0+x1, y0 }, // top right + { x0, y0+y1 }, // bottom left + { x0, y0 } // top left }}; } @@ -15,14 +15,13 @@ struct atlas_texture final static std::array<UnsignedShort, 6> indices(int N); GL::Texture2D& texture() { return tex_; } constexpr int size() const { return dims_.product(); } + constexpr Vector2i tile_size() const { return tile_size_; } atlas_texture(const atlas_texture&) = delete; atlas_texture& operator=(const atlas_texture&) = delete; private: GL::Texture2D tex_; Vector2i size_, dims_, tile_size_; - - static constexpr int MIPMAP_LEVEL = 1; }; } // namespace Magnum::Examples diff --git a/loader-impl.cpp b/loader-impl.cpp index 1f22dfe3..2e82faf5 100644 --- a/loader-impl.cpp +++ b/loader-impl.cpp @@ -25,7 +25,7 @@ struct loader_impl final : loader_ std::string shader(const std::string& filename) override; Trade::ImageData2D tile_texture(const std::string& filename) override; - atlas_ptr tile_atlas(const std::string& filename) override; + atlas_ptr tile_atlas(const std::string& filename, Vector2i size) override; explicit loader_impl(); ~loader_impl() override; @@ -39,10 +39,8 @@ std::string loader_impl::shader(const std::string& filename) return ret; } -atlas_ptr loader_impl::tile_atlas(const std::string& name) +atlas_ptr loader_impl::tile_atlas(const std::string& name, Vector2i size) { - constexpr Vector2i size{8, 4}; // TODO - auto it = atlas_map.find(name); if (it != atlas_map.end()) return it->second; @@ -14,7 +14,7 @@ struct loader_ { virtual std::string shader(const std::string& filename) = 0; virtual Trade::ImageData2D tile_texture(const std::string& filename) = 0; - virtual std::shared_ptr<atlas_texture> tile_atlas(const std::string& filename) = 0; + virtual std::shared_ptr<atlas_texture> tile_atlas(const std::string& filename, Vector2i size) = 0; static void destroy(); loader_(const loader_&) = delete; @@ -24,23 +24,56 @@ namespace Magnum::Examples { struct application final : Platform::Application { + using dpi_policy = Platform::Implementation::Sdl2DpiScalingPolicy; + explicit application(const Arguments& arguments); virtual ~application(); void drawEvent() override; GL::Mesh _mesh; tile_shader _shader; - std::shared_ptr<atlas_texture> atlas = loader.tile_atlas("../share/game/images/tiles.tga"); - - Matrix4x4 make_projection(Vector3 offset); + std::shared_ptr<atlas_texture> atlas = + //loader.tile_atlas("../share/game/images/tiles.tga", {8,4}); + //loader.tile_atlas("../share/game/images/tiles2.tga", {8,5}); + //loader.tile_atlas("../share/game/images/metal1.tga", {2, 2}); + loader.tile_atlas("../share/game/images/floor1.tga", {4, 4}); + + static glm::mat<4, 4, double> make_projection(Vector2i window_size, Vector3 offset); + static float projection_size_ratio(); + Matrix4x4 make_projection(Vector3 offset) const; }; -using dpi_policy = Platform::Implementation::Sdl2DpiScalingPolicy; +float application::projection_size_ratio() +{ + auto m = make_projection({1, 1}, {}); + glm::vec<4, double> pos = glm::vec<4, double>{.5, 0, 0, 1} * m; + return (float)(pos[0] / pos[3]); +} + +glm::mat<4, 4, double> application::make_projection(Vector2i window_size, Vector3 offset) +{ + using vec3 = glm::vec<3, double>; + using mat4 = glm::mat<4, 4, double>; + double x = window_size[0]*.5, y = window_size[1]*.5, w = 2*std::sqrt(x*x+y*y); + auto m = glm::ortho(-x, x, -y, y, -w, w); + //m = glm::ortho<double>(-.5, .5, -.5, .5, -100, 100); + m = glm::scale(m, { 1., 0.6, 1. }); + m = glm::translate(m, { (double)offset[0], (double)-offset[1], (double)offset[2] }); + m = glm::rotate(m, glm::radians(std::asin(1./std::sqrt(2))), vec3(1, 0, 0)); + m = glm::rotate(m, glm::radians(-45.), vec3(0, 0, 1)); + + return glm::mat4(m); +} + +Matrix4x4 application::make_projection(Vector3 offset) const +{ + return Magnum::Matrix4x4{glm::mat4{make_projection(windowSize(), offset)}}; +} application::application(const Arguments& arguments): Platform::Application{arguments, Configuration{} .setTitle("Test") - .setSize({640, 480}, dpi_policy::Physical)} + .setSize({1024, 768}, dpi_policy::Physical)} { struct QuadVertex { Vector3 position; @@ -51,13 +84,14 @@ application::application(const Arguments& arguments): std::vector<QuadVertex> vertices; vertices.reserve(64*64*4); std::vector<UnsignedShort> indices; indices.reserve(256); + auto sz = Vector2{50, 50} * projection_size_ratio(); + int k = 0; for (int j = -2; j <= 2; j++) for (int i = -2; i <= 2; i++) { - constexpr int sz = 48; - auto positions = atlas->floor_quad({(float)(sz*i), (float)(sz*j), 0}, {sz, sz}); - auto texcoords = atlas->texcoords_for_id(((k+5)*101) % atlas->size()); + auto positions = atlas->floor_quad({(float)(sz[0]*i), (float)(sz[1]*j), 0}, sz); + auto texcoords = atlas->texcoords_for_id(k % atlas->size()); auto indices_ = atlas->indices(k); for (unsigned x = 0; x < 4; x++) @@ -82,7 +116,7 @@ void application::drawEvent() { using namespace Math::Literals; _shader - .set_projection(make_projection({0, 0, 0})) + .set_projection(make_projection({})) .set_color(0xffffff_rgbf) .bindTexture(atlas->texture()) .draw(_mesh); @@ -90,21 +124,6 @@ void application::drawEvent() { swapBuffers(); } -Matrix4x4 application::make_projection(Vector3 offset) -{ - using vec3 = glm::vec<3, double, glm::highp>; - using mat4 = glm::mat<4, 4, double, glm::highp>; - auto m = mat4{1}; - auto size = windowSize(); - double x = size[0]*.5, y = size[1]*.5, w = 4*sqrt(x*x+y*y); - m = glm::ortho<double>(-x, x, -y, y, -w, w); - m = glm::translate(m, { (double)offset[0], (double)-offset[1], (double)offset[2] }); - m = glm::scale(m, { 1., 0.6, 1. }); - m = glm::rotate(m, glm::radians(-45.), vec3(1, 0, 0)); - m = glm::rotate(m, glm::radians(0.), vec3(0, 1, 0)); - m = glm::rotate(m, glm::radians(-45.), vec3(0, 0, 1)); - return Matrix4x4{glm::mat4(m)}; -} application::~application() { loader_::destroy(); diff --git a/shaders/tile-shader.vert b/shaders/tile-shader.vert index 670015b1..7a5bd1c3 100644 --- a/shaders/tile-shader.vert +++ b/shaders/tile-shader.vert @@ -1,3 +1,5 @@ +precision highp float; + layout(location = 0) in vec4 position; layout(location = 1) in vec2 textureCoordinates; uniform mat4 projection; @@ -37,14 +37,16 @@ struct local_coords final { 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))); }; struct global_coords final { - decltype(chunk_coords::x) x = 0, y = 0; + 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 std::size_t to_index() const noexcept; + constexpr global_coords(chunk_coords c, local_coords tile) noexcept; }; static_assert(std::is_same_v<decltype(local_coords::x), decltype(local_coords::y)>); @@ -131,8 +133,6 @@ struct hash_chunk final { struct world final { static_assert(sizeof(chunk_coords::x) <= sizeof(std::size_t)/2); - using max_coord_bits = std::integral_constant<decltype(chunk_coords::x), sizeof(chunk_coords::x)*8 * 3 / 4>; - static_assert(max_coord_bits::value*4/3/8 == sizeof(decltype(chunk_coords::x))); explicit world(); template<typename F> std::shared_ptr<chunk> ensure_chunk(chunk_coords xy, F&& fun); @@ -144,8 +144,8 @@ private: template<typename F> std::shared_ptr<chunk> world::ensure_chunk(chunk_coords xy, F&& fun) { - ASSERT(xy.x < 1 << max_coord_bits::value); - ASSERT(xy.y < 1 << max_coord_bits::value); + ASSERT(xy.x < 1 << chunk_coords::max_bits); + ASSERT(xy.y < 1 << chunk_coords::max_bits); auto it = chunks.find(xy); if (it != chunks.end()) @@ -158,10 +158,10 @@ std::shared_ptr<chunk> world::ensure_chunk(chunk_coords xy, F&& fun) } } -constexpr std::size_t global_coords::to_index() const noexcept +constexpr global_coords::global_coords(chunk_coords c, local_coords tile) noexcept : + x{tile.x + ((std::uint32_t)(std::make_unsigned_t<decltype(c.x)>)c.x << chunk_coords::max_bits)}, + y{tile.y + ((std::uint32_t)(std::make_unsigned_t<decltype(c.y)>)c.y << chunk_coords::max_bits)} { - using type = std::make_unsigned_t<decltype(x)>; - return (std::size_t)(type)y * (1 << sizeof(x)*8) + (std::size_t)(type)x; } } //namespace Magnum::Examples |