diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2022-11-07 15:27:08 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-11-07 15:27:08 +0100 |
commit | 151e1f9a56bce31c2703610980c00fc8f527aa6a (patch) | |
tree | c4663ffca0ff35dc2dda04f3cd8e54966683faa2 | |
parent | 9e390f58ea6e4c50d7ba104c5fe3ad97f74fe6f0 (diff) |
wip
-rw-r--r-- | anim/door_close.tga | bin | 3151890 -> 3152411 bytes | |||
-rw-r--r-- | draw/anim.cpp | 25 | ||||
-rw-r--r-- | draw/anim.hpp | 8 | ||||
-rw-r--r-- | draw/wall.cpp | 36 | ||||
-rw-r--r-- | editor/app.cpp | 4 | ||||
-rw-r--r-- | editor/app.hpp | 2 | ||||
-rw-r--r-- | editor/update.cpp | 1 | ||||
-rw-r--r-- | loader/loader-impl.cpp | 10 | ||||
-rw-r--r-- | shaders/tile.frag | 2 | ||||
-rw-r--r-- | src/anim-atlas.cpp | 22 | ||||
-rw-r--r-- | src/scenery.hpp | 3 | ||||
-rw-r--r-- | src/tile-atlas.cpp | 8 |
12 files changed, 77 insertions, 44 deletions
diff --git a/anim/door_close.tga b/anim/door_close.tga Binary files differindex aee729f1..7ad6afba 100644 --- a/anim/door_close.tga +++ b/anim/door_close.tga diff --git a/draw/anim.cpp b/draw/anim.cpp index 0b69e4dd..0e913d08 100644 --- a/draw/anim.cpp +++ b/draw/anim.cpp @@ -1,25 +1,36 @@ #include "anim.hpp" #include "anim-atlas.hpp" #include "shaders/tile.hpp" +#include "wireframe.hpp" +#include "quad-floor.hpp" namespace floormat { -anim_mesh::anim_mesh() = default; +anim_mesh::anim_mesh() +{ + _mesh.setCount(6) + .addVertexBuffer(_vertex_buffer, 0, tile_shader::TextureCoordinates{}) + .addVertexBuffer(_positions_buffer, 0, tile_shader::Position{}) + .setIndexBuffer(_index_buffer, 0, GL::MeshIndexType::UnsignedShort); + CORRADE_INTERNAL_ASSERT(_mesh.isIndexed()); +} std::array<UnsignedShort, 6> anim_mesh::make_index_array() { - using u16 = std::uint16_t; return {{ - (u16)0, (u16)1, (u16)2, - (u16)2, (u16)1, (u16)3, + 0, 1, 2, + 2, 1, 3, }}; } -void anim_mesh::draw(local_coords xy, const anim_atlas& atlas, const anim_frame& frame) +void anim_mesh::draw(tile_shader& shader, const anim_atlas& atlas, const anim_frame& frame, local_coords xy) { - const auto center_ = Vector3(xy.x, xy.y, 0.f) * TILE_SIZE; - const auto pos = atlas.frame_quad(center_, frame); + const auto center = Vector3(xy.x, xy.y, 0.f) * TILE_SIZE; + const auto pos = atlas.frame_quad(center, frame); _positions_buffer.setSubData(0, pos); + const auto texcoords = atlas.texcoords_for_frame(frame); + _vertex_buffer.setSubData(0, texcoords); + shader.draw(_mesh); } } // namespace floormat diff --git a/draw/anim.hpp b/draw/anim.hpp index 60a4e839..85c73bcb 100644 --- a/draw/anim.hpp +++ b/draw/anim.hpp @@ -9,17 +9,18 @@ #include <Magnum/GL/Mesh.h> #include <Magnum/GL/Buffer.h> -namespace floormat::Serialize { struct anim_atlas; struct anim_frame; } +namespace floormat::Serialize { struct anim_frame; } namespace floormat { +struct tile_shader; struct anim_atlas; using anim_frame = Serialize::anim_frame; struct anim_mesh final { anim_mesh(); - void draw(local_coords pos, const anim_atlas& atlas, const anim_frame& frame); + void draw(tile_shader& shader, const anim_atlas& atlas, const anim_frame& frame, local_coords pos); private: struct vertex_data final { Vector2 texcoords; }; @@ -27,10 +28,9 @@ private: 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{quad_data{}}; + _index_buffer{make_index_array()}, _positions_buffer{std::array<Vector3, 4>{}}; }; } // namespace floormat diff --git a/draw/wall.cpp b/draw/wall.cpp index 42d62e49..68f78821 100644 --- a/draw/wall.cpp +++ b/draw/wall.cpp @@ -53,19 +53,31 @@ void wall_mesh::draw(tile_shader& shader, chunk& c) const GL::Texture2D* last_texture = nullptr; Magnum::GL::MeshView mesh{_mesh}; - for (std::size_t i = 0; i < COUNT; i++) + for (std::size_t idx = 0; idx < TILE_COUNT; idx++) { - auto* const tex = textures[i]; - if (!tex) - continue; - 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); - if (auto a = c[i].scenery()) - _anim_mesh.draw(local_coords{i}, *a.atlas, a.atlas->frame(a.frame.r, a.frame.frame)); + for (std::size_t i = idx*2; i <= idx*2+1; i++) + if (auto* const tex = textures[i]; tex) + { + 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); + } + if (auto a = c[idx].scenery(); a.atlas) + { + auto& tex = a.atlas->texture(); + if (&tex != last_texture) + tex.bind(0); + last_texture = &a.atlas->texture(); + auto frame = a.frame; +#if 0 + static std::uint8_t f = 0; + frame.frame = f++ % a.atlas->info().nframes; +#endif + _anim_mesh.draw(shader, *a.atlas, a.atlas->frame(a.frame.r, frame.frame), local_coords{idx}); + } } } diff --git a/editor/app.cpp b/editor/app.cpp index 77f77f83..a2c8b104 100644 --- a/editor/app.cpp +++ b/editor/app.cpp @@ -4,6 +4,7 @@ #include "floormat/settings.hpp" #include "src/loader.hpp" #include "world.hpp" +#include "src/anim-atlas.hpp" #include <algorithm> #include <Corrade/Utility/Arguments.h> @@ -14,7 +15,8 @@ app::app(fm_settings&& opts) : _floor1{loader.tile_atlas("floor-tiles", {44, 4})}, _floor2{loader.tile_atlas("metal1", {2, 2})}, _wall1{loader.tile_atlas("wood2", {2, 1})}, - _wall2{loader.tile_atlas("wood1", {2, 1})} + _wall2{loader.tile_atlas("wood1", {2, 1})}, + _door{loader.anim_atlas("door_close")} { world& w = M->world(); chunk_coords coord{0 ,0}; diff --git a/editor/app.hpp b/editor/app.hpp index aa4f6490..d784fe9a 100644 --- a/editor/app.hpp +++ b/editor/app.hpp @@ -24,6 +24,7 @@ struct floormat_main; struct tile_atlas; struct tile_editor; struct fm_settings; +struct anim_atlas; struct cursor_state final { std::optional<Vector2i> pixel; @@ -98,6 +99,7 @@ private: Containers::Pointer<floormat_main> M; ImGuiIntegration::Context _imgui{NoCreate}; std::shared_ptr<tile_atlas> _floor1, _floor2, _wall1, _wall2; + std::shared_ptr<anim_atlas> _door; wireframe_mesh<wireframe::quad_floor> _wireframe_quad; wireframe_mesh<wireframe::quad_wall_n> _wireframe_wall_n; wireframe_mesh<wireframe::quad_wall_w> _wireframe_wall_w; diff --git a/editor/update.cpp b/editor/update.cpp index 569d81dc..ed9c2561 100644 --- a/editor/update.cpp +++ b/editor/update.cpp @@ -29,6 +29,7 @@ void app::maybe_initialize_chunk_(const chunk_coords& pos, chunk& c) c[{K, K }].wall_west() = { _wall2, 0 }; c[{K, K+1}].wall_north() = { _wall1, 0 }; c[{K+1, K }].wall_west() = { _wall2, 0 }; + c[{K+1, K+1}].scenery() = { _door, {rotation::N, 0} }; } void app::maybe_initialize_chunk([[maybe_unused]] const chunk_coords& pos, [[maybe_unused]] chunk& c) diff --git a/loader/loader-impl.cpp b/loader/loader-impl.cpp index e782314c..c4ba2376 100644 --- a/loader/loader-impl.cpp +++ b/loader/loader-impl.cpp @@ -35,10 +35,11 @@ struct loader_impl final : loader_ { std::optional<Utility::Resource> shader_res; PluginManager::Manager<Trade::AbstractImporter> importer_plugins; - Containers::Pointer<Trade::AbstractImporter> tga_importer = + Containers::Pointer<Trade::AbstractImporter> image_importer = importer_plugins.loadAndInstantiate("AnyImageImporter"); - PluginManager::Manager<Trade::AbstractImageConverter> image_converter_plugins; + Containers::Pointer<Trade::AbstractImporter> tga_importer = + importer_plugins.loadAndInstantiate("TgaImporter"); std::unordered_map<std::string, std::shared_ptr<struct tile_atlas>> tile_atlas_map; std::unordered_map<StringView, std::shared_ptr<struct anim_atlas>> anim_atlas_map; @@ -106,9 +107,10 @@ Trade::ImageData2D loader_impl::texture(const char(&prefix)[N], StringView filen { std::memcpy(filename + len, extension.data(), extension.size()); filename[len + extension.size()] = '\0'; - if (Path::exists(filename) && tga_importer->openFile(filename)) + auto& importer = extension == StringView(".tga") ? tga_importer : image_importer; + if (Path::exists(filename) && importer->openFile(filename)) { - auto img = tga_importer->image2D(0); + auto img = importer->image2D(0); if (!img) fm_abort("can't allocate image for '%s'", filename); auto ret = std::move(*img); diff --git a/shaders/tile.frag b/shaders/tile.frag index 5c070ebe..64372b7b 100644 --- a/shaders/tile.frag +++ b/shaders/tile.frag @@ -7,5 +7,5 @@ noperspective in vec2 frag_texcoords; out vec4 color; void main() { - color = vec4(texture(sampler, frag_texcoords).rgb, 1) * tint; + color = texture(sampler, frag_texcoords) * tint; } diff --git a/src/anim-atlas.cpp b/src/anim-atlas.cpp index 116518d5..093ece73 100644 --- a/src/anim-atlas.cpp +++ b/src/anim-atlas.cpp @@ -73,14 +73,14 @@ auto anim_atlas::texcoords_for_frame(rotation r, std::size_t i) const noexcept - auto anim_atlas::texcoords_for_frame(const anim_frame& frame) const noexcept -> texcoords { - const Vector2 p0(frame.offset), p1(frame.offset + frame.size); + const Vector2 p0(frame.offset), p1(frame.size); const auto x0 = p0.x()+.5f, x1 = p1.x()-1, y0 = p0.y()+.5f, y1 = p1.y()-1; const auto size = _info.pixel_size; return {{ - { (x0+x1) / size[0], (y0+y1) / size[1] }, // bottom right - { (x0+x1) / size[0], y0 / size[1] }, // top right - { x0 / size[0], (y0+y1) / size[1] }, // bottom left - { x0 / size[0], y0 / size[1] }, // top left + { (x0+x1) / size[0], 1 - (y0+y1) / size[1] }, // bottom right + { (x0+x1) / size[0], 1 - y0 / size[1] }, // top right + { x0 / size[0], 1 - (y0+y1) / size[1] }, // bottom left + { x0 / size[0], 1 - y0 / size[1] }, // top left }}; } @@ -91,11 +91,13 @@ auto anim_atlas::frame_quad(const Vector3& center, rotation r, std::size_t i) co auto anim_atlas::frame_quad(const Vector3& center, const anim_frame& frame) noexcept -> quad { - const auto size = Vector2d(frame.size) - Vector2d(frame.ground); - const auto bottom_right = Vector2(tile_shader::unproject({ size[0]*.5, 0 })), - top_right = Vector2(tile_shader::unproject({ size[0]*.5, -size[1] })), - bottom_left = Vector2(tile_shader::unproject({ -size[0]*.5, 0 })), - top_left = Vector2(tile_shader::unproject({ -size[0]*.5, -size[1] })); + const auto size = Vector2d(frame.size); + const double gx = frame.ground[0], gy = frame.ground[1]; + const double sx = size[0]*.25, sy = size[1]*.25; + const auto bottom_right = Vector2(tile_shader::unproject({ -sx - gx, sy - gy })), + top_right = Vector2(tile_shader::unproject({ -sx - gx, -sy - gy })), + bottom_left = Vector2(tile_shader::unproject({ sx - gx, sy - gy })), + top_left = Vector2(tile_shader::unproject({ sx - gx, -sy - gy })); const auto cx = center[0], cy = center[1], cz = center[2]; return {{ { cx + bottom_right[0], cy + bottom_right[1], cz }, diff --git a/src/scenery.hpp b/src/scenery.hpp index a59d6990..5056a22e 100644 --- a/src/scenery.hpp +++ b/src/scenery.hpp @@ -17,8 +17,8 @@ struct scenery final using frame_t = std::uint16_t; - frame_t frame : 12 = NO_FRAME; rotation r : 4 = rotation::N; + frame_t frame : 12 = NO_FRAME; }; static_assert(sizeof(scenery) == sizeof(std::uint16_t)); @@ -26,6 +26,7 @@ static_assert(sizeof(scenery) == sizeof(std::uint16_t)); struct scenery_proto final { std::shared_ptr<anim_atlas> atlas; scenery frame; + operator bool() const noexcept; }; diff --git a/src/tile-atlas.cpp b/src/tile-atlas.cpp index 7960c859..15bb9439 100644 --- a/src/tile-atlas.cpp +++ b/src/tile-atlas.cpp @@ -40,10 +40,10 @@ auto tile_atlas::make_texcoords(Vector2ui pixel_size, Vector2ub tile_count, std: const Vector2 p0(id * sz), p1(sz); const auto x0 = p0.x()+.5f, x1 = p1.x()-1, y0 = p0.y()+.5f, y1 = p1.y()-1; return {{ - { (x0+x1) / pixel_size[0], (y0+y1) / pixel_size[1] }, // bottom right - { (x0+x1) / pixel_size[0], y0 / pixel_size[1] }, // top right - { x0 / pixel_size[0], (y0+y1) / pixel_size[1] }, // bottom left - { x0 / pixel_size[0], y0 / pixel_size[1] }, // top left + { (x0+x1) / pixel_size[0], 1 - (y0+y1) / pixel_size[1] }, // bottom right + { (x0+x1) / pixel_size[0], 1 - y0 / pixel_size[1] }, // top right + { x0 / pixel_size[0], 1 - (y0+y1) / pixel_size[1] }, // bottom left + { x0 / pixel_size[0], 1 - y0 / pixel_size[1] }, // top left }}; } |