multiple tiles

This commit is contained in:
Jay Robson 2024-07-15 17:07:58 +10:00
parent 3d18ccf04e
commit ed761c82bc
19 changed files with 237 additions and 93 deletions

BIN
assets/font/DroidSans.ttf Normal file

Binary file not shown.

Binary file not shown.

View File

@ -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();

View File

@ -13,7 +13,7 @@ namespace Graphics {
std::optional<unsigned int> m_texid;
std::optional<glm::vec4> m_colour;
std::optional<glm::vec4> m_offset;
std::optional<glm::vec3> m_offset;
constexpr Primitive with_matrix(glm::mat4 mat) const {
Primitive p = *this;

View File

@ -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,
};

View File

@ -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 <GL/glew.h>
#include <GLFW/glfw3.h>
@ -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<Tile::BlueBrick>();
m_tool->remesh(mesh, neighbours, {0, 0});
m_model.set(mesh, GL_STATIC_DRAW);
}
@ -57,7 +50,10 @@ 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;
if(map.get_tile(m_intersect)) {
const Tile::TileBase* tile_old = map.get_tile(m_intersect);
unsigned int texid;
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::TileBase> tile;
switch(m_mode) {
case Mode::SET:
tile = std::make_unique<Tile::Empty>();
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();
}

View File

@ -3,6 +3,8 @@
#include "../graphics/context.hpp"
#include "../graphics/gl/model.hpp"
#include "tile/tile_base.hpp"
#include <memory>
namespace World {
struct State;
@ -14,6 +16,7 @@ namespace World {
Graphics::GL::Model m_model;
glm::vec<2, double> m_intersect;
std::unique_ptr<Tile::TileBase> m_tool;
bool m_has_intersect = false;
Mode m_mode;

View File

@ -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);

View File

@ -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<float>() * 0.5f, {0, 0, 1})),
PRIMITIVE_0.with_matrix(glm::rotate(glm::mat4(1), glm::pi<float>() * 1.0f, {0, 0, 1})),
PRIMITIVE_0.with_matrix(glm::rotate(glm::mat4(1), glm::pi<float>() * 1.5f, {0, 0, 1})),
PRIMITIVE_0,
};
std::unique_ptr<Tile::TileBase> m_tiles[N*N];
Graphics::GL::Model m_model;
glm::vec<2, int> m_pos;

View File

@ -1,12 +1,12 @@
#include "state.hpp"
#include "tile/empty.hpp"
#include "tile/yellow_brick.hpp"
#include <memory>
using World::State;
State::State() {
m_map.set_tile({0, 0}, std::make_unique<Tile::Empty>());
m_map.set_tile({0, 0}, std::make_unique<Tile::YellowBrick>());
}
void State::update() {

View File

@ -0,0 +1,38 @@
#include "blue_brick.hpp"
#include "tile_base.hpp"
#include "../../graphics/texture.hpp"
#include <iterator>
using World::Tile::BlueBrick;
void BlueBrick::update() {
}
unsigned int BlueBrick::get_texid() const {
return Graphics::Texture::BLUE_BRICK_FLOOR;
}
std::unique_ptr<World::Tile::TileBase> BlueBrick::clone() const {
return std::make_unique<BlueBrick>(*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 {
}

View File

@ -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<TileBase> clone() const override;
void remesh(Graphics::Mesh& mesh, const TileBase* const* neighbours, glm::vec<2, int> offset) const override;
void render() const override;
};
};

View File

@ -1,11 +0,0 @@
#include "empty.hpp"
using World::Tile::Empty;
void Empty::update() {
}
void Empty::render() const {
}

View File

@ -1,11 +0,0 @@
#pragma once
#include "tile_base.hpp"
namespace World::Tile {
struct Empty : TileBase {
void update() override;
void render() const override;
};
};

View File

@ -1,16 +1,57 @@
#pragma once
#include <glm/ext/matrix_transform.hpp>
#include <glm/ext/scalar_constants.hpp>
#include <glm/gtc/integer.hpp>
#include <memory>
#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<float>() * 0.5f, {0, 0, 1})),
PRIMITIVE_0.with_matrix(glm::rotate(glm::mat4(1), glm::pi<float>() * 1.0f, {0, 0, 1})),
PRIMITIVE_0.with_matrix(glm::rotate(glm::mat4(1), glm::pi<float>() * 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<TileBase> 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;
};
};

View File

@ -0,0 +1,38 @@
#include "white_brick.hpp"
#include "tile_base.hpp"
#include "../../graphics/texture.hpp"
#include <iterator>
using World::Tile::WhiteBrick;
void WhiteBrick::update() {
}
unsigned int WhiteBrick::get_texid() const {
return Graphics::Texture::WHITE_BRICK_FLOOR;
}
std::unique_ptr<World::Tile::TileBase> WhiteBrick::clone() const {
return std::make_unique<WhiteBrick>(*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 {
}

View File

@ -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<TileBase> clone() const override;
void remesh(Graphics::Mesh& mesh, const TileBase* const* neighbours, glm::vec<2, int> offset) const override;
void render() const override;
};
};

View File

@ -0,0 +1,38 @@
#include "yellow_brick.hpp"
#include "tile_base.hpp"
#include "../../graphics/texture.hpp"
#include <iterator>
using World::Tile::YellowBrick;
void YellowBrick::update() {
}
unsigned int YellowBrick::get_texid() const {
return Graphics::Texture::YELLOW_BRICK_FLOOR;
}
std::unique_ptr<World::Tile::TileBase> YellowBrick::clone() const {
return std::make_unique<YellowBrick>(*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 {
}

View File

@ -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<TileBase> clone() const override;
void remesh(Graphics::Mesh& mesh, const TileBase* const* neighbours, glm::vec<2, int> offset) const override;
void render() const override;
};
};