summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2022-11-07 15:27:08 +0100
committerStanislaw Halik <sthalik@misaki.pl>2022-11-07 15:27:08 +0100
commit151e1f9a56bce31c2703610980c00fc8f527aa6a (patch)
treec4663ffca0ff35dc2dda04f3cd8e54966683faa2
parent9e390f58ea6e4c50d7ba104c5fe3ad97f74fe6f0 (diff)
wip
-rw-r--r--anim/door_close.tgabin3151890 -> 3152411 bytes
-rw-r--r--draw/anim.cpp25
-rw-r--r--draw/anim.hpp8
-rw-r--r--draw/wall.cpp36
-rw-r--r--editor/app.cpp4
-rw-r--r--editor/app.hpp2
-rw-r--r--editor/update.cpp1
-rw-r--r--loader/loader-impl.cpp10
-rw-r--r--shaders/tile.frag2
-rw-r--r--src/anim-atlas.cpp22
-rw-r--r--src/scenery.hpp3
-rw-r--r--src/tile-atlas.cpp8
12 files changed, 77 insertions, 44 deletions
diff --git a/anim/door_close.tga b/anim/door_close.tga
index aee729f1..7ad6afba 100644
--- a/anim/door_close.tga
+++ b/anim/door_close.tga
Binary files differ
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
}};
}