diff --git a/assets/font/DroidSans.ttf b/assets/font/DroidSans.ttf new file mode 100644 index 0000000..ad1efca Binary files /dev/null and b/assets/font/DroidSans.ttf differ diff --git a/assets/font/DroidSansMono.ttf b/assets/font/DroidSansMono.ttf new file mode 100644 index 0000000..a007071 Binary files /dev/null and b/assets/font/DroidSansMono.ttf differ diff --git a/src/graphics/mesh.hpp b/src/graphics/mesh.hpp index 87bad68..82da52b 100644 --- a/src/graphics/mesh.hpp +++ b/src/graphics/mesh.hpp @@ -19,7 +19,7 @@ namespace Graphics { v.m_colour *= p.m_colour.value(); } if(p.m_offset.has_value()) { - v.m_pos += p.m_offset.value(); + v.m_pos += glm::vec4{p.m_offset.value(), 0}; } if(p.m_texid.has_value()) { v.m_texid = p.m_texid.value(); diff --git a/src/graphics/primitive.hpp b/src/graphics/primitive.hpp index dc72d80..02814f7 100644 --- a/src/graphics/primitive.hpp +++ b/src/graphics/primitive.hpp @@ -13,7 +13,7 @@ namespace Graphics { std::optional m_texid; std::optional m_colour; - std::optional m_offset; + std::optional m_offset; constexpr Primitive with_matrix(glm::mat4 mat) const { Primitive p = *this; diff --git a/src/graphics/texture.hpp b/src/graphics/texture.hpp index bfdbb38..964b5f9 100644 --- a/src/graphics/texture.hpp +++ b/src/graphics/texture.hpp @@ -9,6 +9,8 @@ namespace Graphics::Texture { inline Image CROSS {"cross.png", Image::Edge::CLAMP}; inline Image YELLOW_BRICK_WALL {"yellow_brick_wall.png", Image::Edge::REPEATING}; inline Image YELLOW_BRICK_FLOOR {"yellow_brick_floor.png", Image::Edge::REPEATING}; + inline Image BLUE_BRICK_WALL {"blue_brick_wall.png", Image::Edge::REPEATING}; + inline Image BLUE_BRICK_FLOOR {"blue_brick_floor.png", Image::Edge::REPEATING}; inline Image WHITE_BRICK_WALL {"white_brick_wall.png", Image::Edge::REPEATING}; inline Image WHITE_BRICK_FLOOR {"white_brick_floor.png", Image::Edge::REPEATING}; @@ -18,6 +20,8 @@ namespace Graphics::Texture { &CROSS, &YELLOW_BRICK_WALL, &YELLOW_BRICK_FLOOR, + &BLUE_BRICK_WALL, + &BLUE_BRICK_FLOOR, &WHITE_BRICK_WALL, &WHITE_BRICK_FLOOR, }; diff --git a/src/world/builder.cpp b/src/world/builder.cpp index d786a15..52f4f4d 100644 --- a/src/world/builder.cpp +++ b/src/world/builder.cpp @@ -2,11 +2,10 @@ #include "builder.hpp" #include "../graphics/window.hpp" #include "../graphics/texture.hpp" -#include "chunk.hpp" #include "map.hpp" #include "player.hpp" #include "state.hpp" -#include "tile/empty.hpp" +#include "tile/blue_brick.hpp" #include "tile/tile_base.hpp" #include #include @@ -18,17 +17,11 @@ using World::Builder; Builder::Builder() { + const Tile::TileBase* neighbours[4] = {nullptr}; + Graphics::Mesh mesh; - auto prim = Chunk::PRIMITIVE_B; - prim.m_texid = Graphics::Texture::YELLOW_BRICK_FLOOR; - mesh.add_primitive(prim); - - for(int i = 0; i < 4; i++) { - prim = Chunk::PRIMITIVE_S[i]; - prim.m_texid = Graphics::Texture::YELLOW_BRICK_WALL; - mesh.add_primitive(prim); - } - + m_tool = std::make_unique(); + m_tool->remesh(mesh, neighbours, {0, 0}); m_model.set(mesh, GL_STATIC_DRAW); } @@ -56,8 +49,11 @@ void Builder::update(State& state) { m_intersect = glm::round(glm::vec<2, double>(near - direction / direction.z * near.z) + player.m_pos); m_has_intersect = true; + + const Tile::TileBase* tile_old = map.get_tile(m_intersect); + unsigned int texid; - if(map.get_tile(m_intersect)) { + if(tile_old) { m_mode = Mode::CLEAR; } else { m_mode = Mode::SET; @@ -70,9 +66,11 @@ void Builder::update(State& state) { std::unique_ptr tile; switch(m_mode) { case Mode::SET: - tile = std::make_unique(); + tile = m_tool->clone(); + texid = tile->get_texid(); break; default: + texid = tile_old->get_texid(); tile = nullptr; } map.set_tile(m_intersect, std::move(tile)); @@ -84,7 +82,7 @@ void Builder::update(State& state) { .m_random_vel = 0.05, .m_duration = 1, .m_size = 0.025, - .m_texid = Graphics::Texture::YELLOW_BRICK_WALL, + .m_texid = texid, }); } @@ -95,16 +93,8 @@ void Builder::render(const Graphics::Context& ctx) const { glm::vec<2, double> pos = glm::round(m_intersect); ctx.set_model_matrix(glm::translate(glm::mat4(1), {pos - ctx.m_transform, 0})); - - switch(m_mode) { - case Mode::CLEAR: - ctx.set_colour_matrix(glm::mat4(1, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 1)); - break; - case Mode::SET: - ctx.set_colour_matrix(glm::mat4(0.5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 1)); - break; - } - + ctx.set_colour_matrix(glm::mat4(1)); m_model.render(GL_TRIANGLES); + m_tool->render(); } diff --git a/src/world/builder.hpp b/src/world/builder.hpp index 5c58a83..5c5d294 100644 --- a/src/world/builder.hpp +++ b/src/world/builder.hpp @@ -3,6 +3,8 @@ #include "../graphics/context.hpp" #include "../graphics/gl/model.hpp" +#include "tile/tile_base.hpp" +#include namespace World { struct State; @@ -14,6 +16,7 @@ namespace World { Graphics::GL::Model m_model; glm::vec<2, double> m_intersect; + std::unique_ptr m_tool; bool m_has_intersect = false; Mode m_mode; diff --git a/src/world/chunk.cpp b/src/world/chunk.cpp index a2d2021..55e0c39 100644 --- a/src/world/chunk.cpp +++ b/src/world/chunk.cpp @@ -73,14 +73,12 @@ void Chunk::update(Map& map) { for(int x = 0; x < N; x++) { for(int y = 0; y < N; y++) { glm::vec<2, int> t_off(x, y); - if(!get(t_off)) { + Tile::TileBase* tile = get(t_off); + if(!tile) { continue; } - auto prim = PRIMITIVE_B; - prim.m_offset = {t_off, 0, 0}; - prim.m_texid = Graphics::Texture::YELLOW_BRICK_FLOOR; - mesh.add_primitive(prim); + const Tile::TileBase* tiles[4]; for(int i = 0; i < std::size(neighbours); i++) { glm::vec<2, int> n_off = neighbours[i] + t_off; @@ -94,13 +92,14 @@ void Chunk::update(Map& map) { } else if(n_off.y == -1) { chunk_check = chunks[3]; } - if(!chunk_check || !chunk_check->get(n_off)) { - prim = PRIMITIVE_S[i]; - prim.m_offset = {t_off, 0, 0}; - prim.m_texid = Graphics::Texture::YELLOW_BRICK_WALL; - mesh.add_primitive(prim); + if(chunk_check) { + tiles[i] = chunk_check->get(n_off); + } else { + tiles[i] = nullptr; } } + + tile->remesh(mesh, tiles, {x, y}); } } m_model.set(mesh, GL_DYNAMIC_DRAW); diff --git a/src/world/chunk.hpp b/src/world/chunk.hpp index e4af606..99ac845 100644 --- a/src/world/chunk.hpp +++ b/src/world/chunk.hpp @@ -17,38 +17,6 @@ namespace World { struct Chunk { static constexpr int N = 16; - static const inline Graphics::Primitive<4, 6> PRIMITIVE_B = { - .m_vertices={ - {.m_pos={-0.5, -0.5, 0, 1}, .m_uv={0, 0}}, - {.m_pos={-0.5, +0.5, 0, 1}, .m_uv={0, 2}}, - {.m_pos={+0.5, -0.5, 0, 1}, .m_uv={2, 0}}, - {.m_pos={+0.5, +0.5, 0, 1}, .m_uv={2, 2}}, - }, - .m_indices={ - 0, 2, 3, - 0, 3, 1, - }, - }; - static const inline Graphics::Primitive<4, 6> PRIMITIVE_0 = { - .m_vertices={ - {.m_pos={-0.5, -0.5, 0.75, 1}, .m_uv={0, 0}}, - {.m_pos={-0.5, -0.5, 0, 1}, .m_uv={0, 1.5}}, - {.m_pos={+0.5, -0.5, 0.75, 1}, .m_uv={2, 0}}, - {.m_pos={+0.5, -0.5, 0, 1}, .m_uv={2, 1.5}}, - }, - .m_indices={ - 0, 2, 3, - 0, 3, 1, - }, - }; - - static const inline Graphics::Primitive<4, 6> PRIMITIVE_S[4] = { - PRIMITIVE_0.with_matrix(glm::rotate(glm::mat4(1), glm::pi() * 0.5f, {0, 0, 1})), - PRIMITIVE_0.with_matrix(glm::rotate(glm::mat4(1), glm::pi() * 1.0f, {0, 0, 1})), - PRIMITIVE_0.with_matrix(glm::rotate(glm::mat4(1), glm::pi() * 1.5f, {0, 0, 1})), - PRIMITIVE_0, - }; - std::unique_ptr m_tiles[N*N]; Graphics::GL::Model m_model; glm::vec<2, int> m_pos; diff --git a/src/world/state.cpp b/src/world/state.cpp index 940a9cc..78b415f 100644 --- a/src/world/state.cpp +++ b/src/world/state.cpp @@ -1,12 +1,12 @@ #include "state.hpp" -#include "tile/empty.hpp" +#include "tile/yellow_brick.hpp" #include using World::State; State::State() { - m_map.set_tile({0, 0}, std::make_unique()); + m_map.set_tile({0, 0}, std::make_unique()); } void State::update() { diff --git a/src/world/tile/blue_brick.cpp b/src/world/tile/blue_brick.cpp new file mode 100644 index 0000000..7b9fb5b --- /dev/null +++ b/src/world/tile/blue_brick.cpp @@ -0,0 +1,38 @@ + +#include "blue_brick.hpp" +#include "tile_base.hpp" +#include "../../graphics/texture.hpp" +#include + +using World::Tile::BlueBrick; + +void BlueBrick::update() { +} + +unsigned int BlueBrick::get_texid() const { + return Graphics::Texture::BLUE_BRICK_FLOOR; +} + +std::unique_ptr BlueBrick::clone() const { + return std::make_unique(*this); +} + +void BlueBrick::remesh(Graphics::Mesh& mesh, const TileBase* const* neighbours, glm::vec<2, int> offset) const { + auto p = TileBase::PRIMITIVE_B; + p.m_texid = Graphics::Texture::BLUE_BRICK_FLOOR; + p.m_offset = {offset, 0}; + mesh.add_primitive(p); + + for(int i = 0; i < std::size(TileBase::PRIMITIVE_S); i++) { + if(!neighbours[i]) { + p = TileBase::PRIMITIVE_S[i]; + p.m_texid = Graphics::Texture::BLUE_BRICK_WALL; + p.m_offset = {offset, 0}; + mesh.add_primitive(p); + } + } +} + +void BlueBrick::render() const { +} + diff --git a/src/world/tile/blue_brick.hpp b/src/world/tile/blue_brick.hpp new file mode 100644 index 0000000..69c5a16 --- /dev/null +++ b/src/world/tile/blue_brick.hpp @@ -0,0 +1,15 @@ + +#pragma once + +#include "tile_base.hpp" + +namespace World::Tile { + struct BlueBrick : TileBase { + void update() override; + unsigned int get_texid() const override; + std::unique_ptr clone() const override; + void remesh(Graphics::Mesh& mesh, const TileBase* const* neighbours, glm::vec<2, int> offset) const override; + void render() const override; + }; +}; + diff --git a/src/world/tile/empty.cpp b/src/world/tile/empty.cpp deleted file mode 100644 index b87d8d5..0000000 --- a/src/world/tile/empty.cpp +++ /dev/null @@ -1,11 +0,0 @@ - -#include "empty.hpp" - -using World::Tile::Empty; - -void Empty::update() { -} - -void Empty::render() const { -} - diff --git a/src/world/tile/empty.hpp b/src/world/tile/empty.hpp deleted file mode 100644 index 7f98162..0000000 --- a/src/world/tile/empty.hpp +++ /dev/null @@ -1,11 +0,0 @@ - -#pragma once - -#include "tile_base.hpp" -namespace World::Tile { - struct Empty : TileBase { - void update() override; - void render() const override; - }; -}; - diff --git a/src/world/tile/tile_base.hpp b/src/world/tile/tile_base.hpp index 681637d..174f57f 100644 --- a/src/world/tile/tile_base.hpp +++ b/src/world/tile/tile_base.hpp @@ -1,16 +1,57 @@ #pragma once +#include +#include #include +#include +#include "../../graphics/mesh.hpp" namespace World::Tile { struct TileBase { + + static const inline Graphics::Primitive<4, 6> PRIMITIVE_B = { + .m_vertices={ + {.m_pos={-0.5, -0.5, 0, 1}, .m_uv={0, 0}}, + {.m_pos={-0.5, +0.5, 0, 1}, .m_uv={0, 2}}, + {.m_pos={+0.5, -0.5, 0, 1}, .m_uv={2, 0}}, + {.m_pos={+0.5, +0.5, 0, 1}, .m_uv={2, 2}}, + }, + .m_indices={ + 0, 2, 3, + 0, 3, 1, + }, + }; + private: + static const inline Graphics::Primitive<4, 6> PRIMITIVE_0 = { + .m_vertices={ + {.m_pos={-0.5, -0.5, 0.75, 1}, .m_uv={0, 0}}, + {.m_pos={-0.5, -0.5, 0, 1}, .m_uv={0, 1.5}}, + {.m_pos={+0.5, -0.5, 0.75, 1}, .m_uv={2, 0}}, + {.m_pos={+0.5, -0.5, 0, 1}, .m_uv={2, 1.5}}, + }, + .m_indices={ + 0, 2, 3, + 0, 3, 1, + }, + }; + public: + static const inline Graphics::Primitive<4, 6> PRIMITIVE_S[4] = { + PRIMITIVE_0.with_matrix(glm::rotate(glm::mat4(1), glm::pi() * 0.5f, {0, 0, 1})), + PRIMITIVE_0.with_matrix(glm::rotate(glm::mat4(1), glm::pi() * 1.0f, {0, 0, 1})), + PRIMITIVE_0.with_matrix(glm::rotate(glm::mat4(1), glm::pi() * 1.5f, {0, 0, 1})), + PRIMITIVE_0, + }; + int m_facing = 0; glm::vec<2, int> m_pos; virtual ~TileBase() = default; virtual void update() = 0; + virtual unsigned int get_texid() const = 0; + virtual std::unique_ptr clone() const = 0; + virtual void remesh(Graphics::Mesh& mesh, TileBase const* const* neighbours, glm::vec<2, int> offset) const = 0; virtual void render() const = 0; }; }; diff --git a/src/world/tile/white_brick.cpp b/src/world/tile/white_brick.cpp new file mode 100644 index 0000000..3a56284 --- /dev/null +++ b/src/world/tile/white_brick.cpp @@ -0,0 +1,38 @@ + +#include "white_brick.hpp" +#include "tile_base.hpp" +#include "../../graphics/texture.hpp" +#include + +using World::Tile::WhiteBrick; + +void WhiteBrick::update() { +} + +unsigned int WhiteBrick::get_texid() const { + return Graphics::Texture::WHITE_BRICK_FLOOR; +} + +std::unique_ptr WhiteBrick::clone() const { + return std::make_unique(*this); +} + +void WhiteBrick::remesh(Graphics::Mesh& mesh, const TileBase* const* neighbours, glm::vec<2, int> offset) const { + auto p = TileBase::PRIMITIVE_B; + p.m_texid = Graphics::Texture::WHITE_BRICK_FLOOR; + p.m_offset = {offset, 0}; + mesh.add_primitive(p); + + for(int i = 0; i < std::size(TileBase::PRIMITIVE_S); i++) { + if(!neighbours[i]) { + p = TileBase::PRIMITIVE_S[i]; + p.m_texid = Graphics::Texture::WHITE_BRICK_WALL; + p.m_offset = {offset, 0}; + mesh.add_primitive(p); + } + } +} + +void WhiteBrick::render() const { +} + diff --git a/src/world/tile/white_brick.hpp b/src/world/tile/white_brick.hpp new file mode 100644 index 0000000..e7dc63c --- /dev/null +++ b/src/world/tile/white_brick.hpp @@ -0,0 +1,16 @@ + +#pragma once + +#include "tile_base.hpp" + +namespace World::Tile { + struct WhiteBrick : TileBase { + void update() override; + unsigned int get_texid() const override; + std::unique_ptr clone() const override; + void remesh(Graphics::Mesh& mesh, const TileBase* const* neighbours, glm::vec<2, int> offset) const override; + void render() const override; + + }; +}; + diff --git a/src/world/tile/yellow_brick.cpp b/src/world/tile/yellow_brick.cpp new file mode 100644 index 0000000..33407a5 --- /dev/null +++ b/src/world/tile/yellow_brick.cpp @@ -0,0 +1,38 @@ + +#include "yellow_brick.hpp" +#include "tile_base.hpp" +#include "../../graphics/texture.hpp" +#include + +using World::Tile::YellowBrick; + +void YellowBrick::update() { +} + +unsigned int YellowBrick::get_texid() const { + return Graphics::Texture::YELLOW_BRICK_FLOOR; +} + +std::unique_ptr YellowBrick::clone() const { + return std::make_unique(*this); +} + +void YellowBrick::remesh(Graphics::Mesh& mesh, const TileBase* const* neighbours, glm::vec<2, int> offset) const { + auto p = TileBase::PRIMITIVE_B; + p.m_texid = Graphics::Texture::YELLOW_BRICK_FLOOR; + p.m_offset = {offset, 0}; + mesh.add_primitive(p); + + for(int i = 0; i < std::size(TileBase::PRIMITIVE_S); i++) { + if(!neighbours[i]) { + p = TileBase::PRIMITIVE_S[i]; + p.m_texid = Graphics::Texture::YELLOW_BRICK_WALL; + p.m_offset = {offset, 0}; + mesh.add_primitive(p); + } + } +} + +void YellowBrick::render() const { +} + diff --git a/src/world/tile/yellow_brick.hpp b/src/world/tile/yellow_brick.hpp new file mode 100644 index 0000000..41d201a --- /dev/null +++ b/src/world/tile/yellow_brick.hpp @@ -0,0 +1,16 @@ + +#pragma once + +#include "tile_base.hpp" + +namespace World::Tile { + struct YellowBrick : TileBase { + void update() override; + unsigned int get_texid() const override; + std::unique_ptr clone() const override; + void remesh(Graphics::Mesh& mesh, const TileBase* const* neighbours, glm::vec<2, int> offset) const override; + void render() const override; + + }; +}; +