summaryrefslogtreecommitdiffhomepage
path: root/draw/anim.cpp
blob: aa5ee1f676efb0112f8837a0ee8757b1abbf10ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include "anim.hpp"
#include "anim-atlas.hpp"
#include "chunk.hpp"
#include "shaders/tile.hpp"
#include <Magnum/GL/Texture.h>

namespace floormat {

anim_mesh::anim_mesh()
{
    _mesh.setCount(6)
        .addVertexBuffer(_vertex_buffer, 0, tile_shader::Position{}, tile_shader::TextureCoordinates{}, tile_shader::Depth{})
        .setIndexBuffer(_index_buffer, 0, GL::MeshIndexType::UnsignedShort);
    CORRADE_INTERNAL_ASSERT(_mesh.isIndexed());
}

std::array<UnsignedShort, 6> anim_mesh::make_index_array()
{
    return {{
        0, 1, 2,
        2, 1, 3,
    }};
}

void anim_mesh::draw(tile_shader& shader, chunk& c)
{
    for (std::size_t i = 0; i < TILE_COUNT; i++)
    {
        const local_coords pos{i};
        if (auto [atlas, s] = c[pos].scenery(); atlas)
        {
            draw(shader, *atlas, s.r, s.frame, pos);
#if 1
            // todo debugging
            static std::size_t N = 0;
            N++;
            auto nframes = atlas->info().nframes;
            if (N > nframes*3)
                N = 0;
            s.frame = (scenery::frame_t)std::min(N, nframes-1);
#endif
        }
    }
}

void anim_mesh::draw(tile_shader& shader, anim_atlas& atlas, rotation r, std::size_t frame, local_coords xy)
{
    const auto center = Vector3(xy.x, xy.y, 0.f) * TILE_SIZE;
    const auto pos = atlas.frame_quad(center, r, frame);
    const auto texcoords = atlas.texcoords_for_frame(r, frame);
    const float depth = tile_shader::depth_value(xy, .25f);
    quad_data array;
    for (std::size_t i = 0; i < 4; i++)
        array[i] = { pos[i], texcoords[i], depth };
    _vertex_buffer.setSubData(0, array);
    atlas.texture().bind(0);
    shader.draw(_mesh);
}

} // namespace floormat