added tile placement
This commit is contained in:
parent
ed761c82bc
commit
bffeac4099
Binary file not shown.
Before Width: | Height: | Size: 775 B After Width: | Height: | Size: 4.4 KiB |
|
@ -5,6 +5,7 @@
|
|||
#include "vertex.hpp"
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
|
@ -82,7 +83,7 @@ void Particles::render(const Context& ctx) const {
|
|||
}
|
||||
|
||||
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
|
||||
ctx.set_model_matrix(glm::mat4(1));
|
||||
ctx.set_model_matrix(glm::translate(glm::mat4(1), {-ctx.m_transform, 0}));
|
||||
ctx.set_colour_matrix(glm::mat4(1));
|
||||
|
||||
glBindVertexArray(m_vao);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
namespace Graphics::Texture {
|
||||
inline Image MISSING {"missing.png", Image::Edge::REPEATING};
|
||||
inline Image WHITE {"white.png", Image::Edge::REPEATING};
|
||||
inline Image CROSS {"cross.png", Image::Edge::CLAMP};
|
||||
inline Image CROSS {"cross.png", Image::Edge::REPEATING};
|
||||
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};
|
||||
|
|
|
@ -37,7 +37,7 @@ static void cb_keypress(GLFWwindow* win, int key, int sc, int action, int mods)
|
|||
|
||||
static bool clicked_from_cb = false;
|
||||
|
||||
void cb_mouse_button(GLFWwindow* win, int button, int action, int mods) {
|
||||
static void cb_mouse_button(GLFWwindow* win, int button, int action, int mods) {
|
||||
if(button == GLFW_MOUSE_BUTTON_RIGHT) {
|
||||
if(action == GLFW_PRESS) {
|
||||
Window::mouse_locked = true;
|
||||
|
@ -53,6 +53,12 @@ void cb_mouse_button(GLFWwindow* win, int button, int action, int mods) {
|
|||
}
|
||||
}
|
||||
|
||||
static double scroll_from_cb = 0;
|
||||
|
||||
static void cb_scroll(GLFWwindow* win, double x, double y) {
|
||||
scroll_from_cb = y;
|
||||
}
|
||||
|
||||
float Window::get_aspect() {
|
||||
return (float)Window::size.x / (float)Window::size.y;
|
||||
}
|
||||
|
@ -67,6 +73,7 @@ Window::Window() {
|
|||
glfwSetFramebufferSizeCallback(m_handle, cb_framebuffer_size);
|
||||
glfwSetMouseButtonCallback(m_handle, cb_mouse_button);
|
||||
glfwSetKeyCallback(m_handle, cb_keypress);
|
||||
glfwSetScrollCallback(m_handle, cb_scroll);
|
||||
glfwSwapInterval(1);
|
||||
|
||||
assert(glewInit() == GLEW_OK);
|
||||
|
@ -100,6 +107,13 @@ void Window::update() const {
|
|||
} else {
|
||||
Window::clicked = false;
|
||||
}
|
||||
|
||||
if(scroll_from_cb) {
|
||||
Window::scroll = scroll_from_cb;
|
||||
scroll_from_cb = 0;
|
||||
} else {
|
||||
Window::scroll = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Window::swap_buffers() const {
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace Graphics {
|
|||
inline static glm::vec<2, int> size;
|
||||
inline static bool mouse_locked = false;
|
||||
inline static bool clicked = false;
|
||||
inline static double scroll = 0;
|
||||
|
||||
GLFWwindow* m_handle;
|
||||
|
||||
|
|
|
@ -1,36 +1,34 @@
|
|||
|
||||
#include "builder.hpp"
|
||||
#include "../graphics/window.hpp"
|
||||
#include "../graphics/texture.hpp"
|
||||
#include "map.hpp"
|
||||
#include "player.hpp"
|
||||
#include "state.hpp"
|
||||
#include "tile/blue_brick.hpp"
|
||||
#include "tile/tile_base.hpp"
|
||||
#include "tile/white_brick.hpp"
|
||||
#include "tile/yellow_brick.hpp"
|
||||
#include "../util/math/mod.hpp"
|
||||
#include "../graphics/texture.hpp"
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <algorithm>
|
||||
#include <glm/common.hpp>
|
||||
#include <glm/ext/matrix_projection.hpp>
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
#include <memory>
|
||||
|
||||
using World::Builder;
|
||||
|
||||
Builder::Builder() {
|
||||
const Tile::TileBase* neighbours[4] = {nullptr};
|
||||
|
||||
Graphics::Mesh mesh;
|
||||
m_tool = std::make_unique<Tile::BlueBrick>();
|
||||
m_tool->remesh(mesh, neighbours, {0, 0});
|
||||
m_model.set(mesh, GL_STATIC_DRAW);
|
||||
m_tools.push_back(nullptr);
|
||||
m_tools.push_back(std::make_unique<Tile::YellowBrick>());
|
||||
m_tools.push_back(std::make_unique<Tile::BlueBrick>());
|
||||
m_tools.push_back(std::make_unique<Tile::WhiteBrick>());
|
||||
|
||||
remesh_tool();
|
||||
}
|
||||
|
||||
void Builder::update(State& state) {
|
||||
m_has_intersect = false;
|
||||
if(Graphics::Window::mouse_locked) {
|
||||
return;
|
||||
}
|
||||
|
||||
void Builder::do_click(State& state) {
|
||||
Player& player = state.m_player;
|
||||
Map& map = state.m_map;
|
||||
|
||||
|
@ -40,7 +38,6 @@ void Builder::update(State& state) {
|
|||
glm::vec<3, double> near = glm::unProject<float>(glm::vec3(mpos, -1), player.m_view, player.m_projection, glm::vec4(0, 0, Graphics::Window::size));
|
||||
glm::vec<3, double> far = glm::unProject<float>(glm::vec3(mpos, 1), player.m_view, player.m_projection, glm::vec4(0, 0, Graphics::Window::size));
|
||||
glm::vec<3, double> direction = far - near;
|
||||
const glm::vec<2, double> CHECK_TILES[] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
|
||||
bool found = false;
|
||||
|
||||
if(direction.z >= 0) {
|
||||
|
@ -48,32 +45,40 @@ void Builder::update(State& state) {
|
|||
}
|
||||
|
||||
m_intersect = glm::round(glm::vec<2, double>(near - direction / direction.z * near.z) + player.m_pos);
|
||||
|
||||
const Tile::TileBase* tile_cur = map.get_tile(m_intersect);
|
||||
const Tile::TileBase* tile_next = m_tools[m_tool_index].get();
|
||||
|
||||
if(tile_next && !tile_next->can_place(tile_cur) || !tile_next && !tile_cur) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_has_intersect = true;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if(!m_has_intersect || !Graphics::Window::clicked) {
|
||||
if(!Graphics::Window::clicked) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<Tile::TileBase> tile;
|
||||
switch(m_mode) {
|
||||
case Mode::SET:
|
||||
tile = m_tool->clone();
|
||||
texid = tile->get_texid();
|
||||
break;
|
||||
default:
|
||||
texid = tile_old->get_texid();
|
||||
tile = nullptr;
|
||||
unsigned int texid;
|
||||
bool texid_use_old = false;
|
||||
|
||||
if(tile_next) {
|
||||
tile = tile_next->clone();
|
||||
texid = tile_next->get_break_texture();
|
||||
} else {
|
||||
texid_use_old = true;
|
||||
}
|
||||
|
||||
tile = map.set_tile(m_intersect, std::move(tile));
|
||||
|
||||
if(texid_use_old) {
|
||||
if(tile) {
|
||||
texid = tile->get_break_texture();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
map.set_tile(m_intersect, std::move(tile));
|
||||
|
||||
state.m_particles.add({
|
||||
.m_pos = {m_intersect, 0.75/2},
|
||||
|
@ -86,6 +91,48 @@ void Builder::update(State& state) {
|
|||
});
|
||||
}
|
||||
|
||||
void Builder::remesh_tool() {
|
||||
Graphics::Mesh mesh;
|
||||
if(m_tools[m_tool_index]) {
|
||||
const Tile::TileBase* neighbours[4] = {nullptr};
|
||||
m_tools[m_tool_index]->remesh(mesh, neighbours, {0, 0});
|
||||
} else {
|
||||
Graphics::Primitive<4, 6> prim = {
|
||||
.m_vertices={
|
||||
{.m_pos={-0.5, -0.5, 0.05, 1}, .m_uv={0, 0}},
|
||||
{.m_pos={+0.5, -0.5, 0.05, 1}, .m_uv={2, 0}},
|
||||
{.m_pos={-0.5, +0.5, 0.05, 1}, .m_uv={0, 2}},
|
||||
{.m_pos={+0.5, +0.5, 0.05, 1}, .m_uv={2, 2}},
|
||||
},
|
||||
.m_indices={
|
||||
0, 3, 2,
|
||||
0, 1, 3,
|
||||
},
|
||||
};
|
||||
prim.m_texid = Graphics::Texture::CROSS;
|
||||
mesh.add_primitive(prim);
|
||||
}
|
||||
m_model.set(mesh, GL_DYNAMIC_DRAW);
|
||||
}
|
||||
|
||||
void Builder::select_tool() {
|
||||
int offset = std::clamp((int)std::round(Graphics::Window::scroll), -1, 1);
|
||||
if(offset == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_tool_index = Util::Math::mod(m_tool_index + offset, m_tools.size());
|
||||
remesh_tool();
|
||||
}
|
||||
|
||||
void Builder::update(State& state) {
|
||||
m_has_intersect = false;
|
||||
if(!Graphics::Window::mouse_locked) {
|
||||
select_tool();
|
||||
do_click(state);
|
||||
}
|
||||
}
|
||||
|
||||
void Builder::render(const Graphics::Context& ctx) const {
|
||||
if(!m_has_intersect) {
|
||||
return;
|
||||
|
@ -95,6 +142,5 @@ void Builder::render(const Graphics::Context& ctx) const {
|
|||
ctx.set_model_matrix(glm::translate(glm::mat4(1), {pos - ctx.m_transform, 0}));
|
||||
ctx.set_colour_matrix(glm::mat4(1));
|
||||
m_model.render(GL_TRIANGLES);
|
||||
m_tool->render();
|
||||
}
|
||||
|
||||
|
|
|
@ -14,16 +14,23 @@ namespace World {
|
|||
CLEAR,
|
||||
};
|
||||
|
||||
std::vector<std::unique_ptr<Tile::TileBase>> m_tools;
|
||||
|
||||
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;
|
||||
int m_tool_index = 1;
|
||||
|
||||
Builder();
|
||||
|
||||
void update(State& state);
|
||||
void render(const Graphics::Context& ctx) const;
|
||||
|
||||
private:
|
||||
|
||||
void do_click(State& state);
|
||||
void select_tool();
|
||||
void remesh_tool();
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -2,13 +2,11 @@
|
|||
#include <GL/glew.h>
|
||||
#include "chunk.hpp"
|
||||
#include "tile/tile_base.hpp"
|
||||
#include "../graphics/texture.hpp"
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
#include <glm/ext/quaternion_transform.hpp>
|
||||
#include <glm/ext/scalar_constants.hpp>
|
||||
#include <glm/ext/vector_float3.hpp>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
|
||||
using World::Chunk;
|
||||
using World::Tile::TileBase;
|
||||
|
@ -21,38 +19,34 @@ Chunk::Chunk(glm::vec<2, int> pos) {
|
|||
m_pos = pos;
|
||||
}
|
||||
|
||||
TileBase* Chunk::get(glm::vec<2, int> p) {
|
||||
p = get_pos_mod(p);
|
||||
return m_tiles[p.x * N + p.y].get();
|
||||
}
|
||||
|
||||
const TileBase* Chunk::get(glm::vec<2, int> p) const {
|
||||
p = get_pos_mod(p);
|
||||
return m_tiles[p.x * N + p.y].get();
|
||||
}
|
||||
|
||||
TileBase* Chunk::set(glm::vec<2, int> p, std::unique_ptr<TileBase> v) {
|
||||
TileBase* r = v.get();
|
||||
TileBase* Chunk::get(glm::vec<2, int> p) {
|
||||
p = get_pos_mod(p);
|
||||
m_tiles[p.x * N + p.y].swap(v);
|
||||
return m_tiles[p.x * N + p.y].get();
|
||||
}
|
||||
|
||||
if(r && !v) {
|
||||
m_used_tiles += 1;
|
||||
}
|
||||
else if(!r && v) {
|
||||
std::unique_ptr<TileBase> Chunk::set(glm::vec<2, int> p, std::unique_ptr<TileBase> v) {
|
||||
p = get_pos_mod(p);
|
||||
|
||||
bool is_empty_in = v == nullptr;
|
||||
std::swap(m_tiles[p.x * N + p.y], v);
|
||||
|
||||
if(is_empty_in && v) {
|
||||
m_used_tiles -= 1;
|
||||
}
|
||||
else if(!is_empty_in && !v) {
|
||||
m_used_tiles += 1;
|
||||
}
|
||||
|
||||
m_dirty = true;
|
||||
return r;
|
||||
return v;
|
||||
}
|
||||
|
||||
void Chunk::update(Map& map) {
|
||||
for(auto& tile : m_tiles) {
|
||||
if(tile) {
|
||||
tile->update();
|
||||
}
|
||||
}
|
||||
if(!m_dirty) {
|
||||
return;
|
||||
}
|
||||
|
@ -73,11 +67,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);
|
||||
Tile::TileBase* tile = get(t_off);
|
||||
const Tile::TileBase* tile = get(t_off);
|
||||
|
||||
if(!tile) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
const Tile::TileBase* tiles[4];
|
||||
|
||||
for(int i = 0; i < std::size(neighbours); i++) {
|
||||
|
@ -110,11 +105,5 @@ void Chunk::render(const Graphics::Context& ctx) const {
|
|||
ctx.set_model_matrix(glm::translate(glm::mat4(1), {glm::vec<2, double>(m_pos) - ctx.m_transform, 0}));
|
||||
ctx.set_colour_matrix(glm::mat4(1));
|
||||
m_model.render(GL_TRIANGLES);
|
||||
|
||||
for(auto& tile : m_tiles) {
|
||||
if(tile) {
|
||||
tile->render();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,13 +11,12 @@ namespace World {
|
|||
#include "tile/tile_base.hpp"
|
||||
#include "../graphics/gl/model.hpp"
|
||||
#include <glm/gtc/integer.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace World {
|
||||
struct Chunk {
|
||||
static constexpr int N = 16;
|
||||
|
||||
std::unique_ptr<Tile::TileBase> m_tiles[N*N];
|
||||
std::unique_ptr<Tile::TileBase> m_tiles[N*N] = {{}};
|
||||
Graphics::GL::Model m_model;
|
||||
glm::vec<2, int> m_pos;
|
||||
int m_used_tiles = 0;
|
||||
|
@ -27,9 +26,9 @@ namespace World {
|
|||
|
||||
void update(Map& map);
|
||||
void render(const Graphics::Context& ctx) const;
|
||||
Tile::TileBase* get(glm::vec<2, int> p);
|
||||
const Tile::TileBase* get(glm::vec<2, int> p) const;
|
||||
Tile::TileBase* set(glm::vec<2, int> p, std::unique_ptr<Tile::TileBase> v);
|
||||
Tile::TileBase* get(glm::vec<2, int> p);
|
||||
std::unique_ptr<Tile::TileBase> set(glm::vec<2, int> p, std::unique_ptr<Tile::TileBase> v);
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -56,39 +56,37 @@ void Map::mark_chunk_dirty(glm::vec<2, int> pos) {
|
|||
}
|
||||
}
|
||||
|
||||
TileBase* Map::get_tile(glm::vec<2, int> pos) {
|
||||
Chunk* c = get_chunk(pos);
|
||||
return c ? c->get(pos) : nullptr;
|
||||
}
|
||||
|
||||
const TileBase* Map::get_tile(glm::vec<2, int> pos) const {
|
||||
const Chunk* c = get_chunk(pos);
|
||||
return c ? c->get(pos) : nullptr;
|
||||
}
|
||||
|
||||
TileBase* Map::set_tile(glm::vec<2, int> pos, std::unique_ptr<TileBase> tile) {
|
||||
TileBase* Map::get_tile(glm::vec<2, int> pos) {
|
||||
Chunk* c = get_chunk(pos);
|
||||
return c ? c->get(pos) : nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<TileBase> Map::set_tile(glm::vec<2, int> pos, std::unique_ptr<TileBase> tile) {
|
||||
uint64_t cid = get_chunk_id(pos);
|
||||
auto it = m_chunks.find(cid);
|
||||
if(tile) {
|
||||
tile->m_pos = pos;
|
||||
if(it == m_chunks.end()) {
|
||||
it = m_chunks.try_emplace(cid, pos - get_pos_mod(pos)).first;
|
||||
}
|
||||
} else if(it == m_chunks.end()) {
|
||||
return nullptr;
|
||||
|
||||
if(it == m_chunks.end()) {
|
||||
it = m_chunks.try_emplace(cid, pos - get_pos_mod(pos)).first;
|
||||
}
|
||||
Chunk* c = &it->second;
|
||||
TileBase* tile_p = c->set(pos, std::move(tile));
|
||||
|
||||
Chunk& c = it->second;
|
||||
tile = c.set(pos, std::move(tile));
|
||||
|
||||
mark_chunk_dirty(pos + glm::vec<2, int>(1, 0));
|
||||
mark_chunk_dirty(pos + glm::vec<2, int>(0, 1));
|
||||
mark_chunk_dirty(pos + glm::vec<2, int>(-1, 0));
|
||||
mark_chunk_dirty(pos + glm::vec<2, int>(0, -1));
|
||||
|
||||
if(!tile_p && c->m_used_tiles == 0) {
|
||||
if(c.m_used_tiles <= 0) {
|
||||
m_chunks.erase(it);
|
||||
}
|
||||
|
||||
return tile_p;
|
||||
return tile;
|
||||
}
|
||||
|
||||
void Map::update() {
|
||||
|
|
|
@ -11,21 +11,21 @@ namespace World {
|
|||
#include <glm/gtc/integer.hpp>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace World {
|
||||
struct State;
|
||||
struct Map {
|
||||
static constexpr int N = 16;
|
||||
std::map<uint64_t, Chunk> m_chunks;
|
||||
|
||||
const Chunk* get_chunk(glm::vec<2, int> pos) const;
|
||||
|
||||
Tile::TileBase* get_tile(glm::vec<2, int> pos);
|
||||
const Tile::TileBase* get_tile(glm::vec<2, int> pos) const;
|
||||
|
||||
Chunk* get_chunk(glm::vec<2, int> pos);
|
||||
const Chunk* get_chunk(glm::vec<2, int> pos) const;
|
||||
|
||||
Chunk* get_or_generate_chunk(glm::vec<2, int> pos);
|
||||
Tile::TileBase* get_tile(glm::vec<2, int> pos);
|
||||
Tile::TileBase* set_tile(glm::vec<2, int> pos, std::unique_ptr<Tile::TileBase> tile);
|
||||
std::unique_ptr<Tile::TileBase> set_tile(glm::vec<2, int> pos, std::unique_ptr<Tile::TileBase> tile);
|
||||
|
||||
void update();
|
||||
void render(const Graphics::Context& ctx) const;
|
||||
|
|
|
@ -56,8 +56,9 @@ void Player::update() {
|
|||
m_cursor_last = cursor;
|
||||
|
||||
if(Graphics::Window::mouse_locked) {
|
||||
m_pitch = std::fmod(m_pitch + cursor_diff.x * 0.0025, glm::pi<double>() * 2);
|
||||
m_yaw = std::clamp(m_yaw - cursor_diff.y * 0.0025, 0.0, glm::pi<double>() * 0.5);
|
||||
double pi = glm::pi<double>();
|
||||
m_pitch = std::fmod(m_pitch + cursor_diff.x * 0.0025, pi*2);
|
||||
m_yaw = std::clamp(m_yaw - cursor_diff.y * 0.0025, 0.0, pi*0.5);
|
||||
}
|
||||
|
||||
m_vel += m_accel;
|
||||
|
@ -68,8 +69,9 @@ void Player::update() {
|
|||
mat = glm::translate(mat, {0, 0, -m_distance});
|
||||
mat = glm::rotate(mat, (float)m_yaw, {-1, 0, 0});
|
||||
mat = glm::rotate(mat, (float)m_pitch, {0, 0, 1});
|
||||
mat = glm::translate(mat, {0, 0, -0.25});
|
||||
|
||||
m_view = mat;
|
||||
m_projection = glm::perspective(glm::radians(90.0f), Graphics::Window::get_aspect(), 0.01f, 10.f);
|
||||
m_projection = glm::perspective(glm::radians(90.0f), Graphics::Window::get_aspect(), 0.01f, 100.f);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
#include "state.hpp"
|
||||
#include "tile/yellow_brick.hpp"
|
||||
#include <memory>
|
||||
|
||||
using World::State;
|
||||
|
||||
|
|
|
@ -2,37 +2,23 @@
|
|||
#include "blue_brick.hpp"
|
||||
#include "tile_base.hpp"
|
||||
#include "../../graphics/texture.hpp"
|
||||
#include <iterator>
|
||||
|
||||
using World::Tile::BlueBrick;
|
||||
using World::Tile::TileBase;
|
||||
|
||||
void BlueBrick::update() {
|
||||
}
|
||||
|
||||
unsigned int BlueBrick::get_texid() const {
|
||||
unsigned int BlueBrick::get_break_texture() const {
|
||||
return Graphics::Texture::BLUE_BRICK_FLOOR;
|
||||
}
|
||||
|
||||
std::unique_ptr<World::Tile::TileBase> BlueBrick::clone() const {
|
||||
std::unique_ptr<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);
|
||||
}
|
||||
}
|
||||
remesh_room(mesh, neighbours, offset, Graphics::Texture::BLUE_BRICK_FLOOR, Graphics::Texture::BLUE_BRICK_WALL, Graphics::Texture::BLUE_BRICK_FLOOR, 0.75);
|
||||
}
|
||||
|
||||
void BlueBrick::render() const {
|
||||
bool BlueBrick::can_place(const TileBase* o) const {
|
||||
return o == nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "tile_base.hpp"
|
||||
#include "tile_room.hpp"
|
||||
|
||||
namespace World::Tile {
|
||||
struct BlueBrick : TileBase {
|
||||
void update() override;
|
||||
unsigned int get_texid() const override;
|
||||
std::unique_ptr<TileBase> clone() const override;
|
||||
struct BlueBrick : TileRoom {
|
||||
unsigned int get_break_texture() const override;
|
||||
void remesh(Graphics::Mesh& mesh, const TileBase* const* neighbours, glm::vec<2, int> offset) const override;
|
||||
void render() const override;
|
||||
std::unique_ptr<TileBase> clone() const override;
|
||||
bool can_place(const TileBase* o) const override;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
#include "tile_base.hpp"
|
||||
|
||||
using World::Tile::TileBase;
|
||||
|
||||
unsigned int TileBase::get_break_texture() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TileBase::remesh(Graphics::Mesh& mesh, const TileBase* const* neighbours, glm::vec<2, int> offset) const {
|
||||
}
|
||||
|
|
@ -9,50 +9,13 @@
|
|||
|
||||
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 unsigned int get_break_texture() const = 0;
|
||||
virtual void remesh(Graphics::Mesh& mesh, const TileBase* const* neighbours, glm::vec<2, int> offset) 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;
|
||||
virtual bool can_place(const TileBase* o) const = 0;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
|
||||
#include "tile_room.hpp"
|
||||
#include "tile_base.hpp"
|
||||
|
||||
using World::Tile::TileBase;
|
||||
using World::Tile::TileRoom;
|
||||
|
||||
static const Graphics::Primitive<4, 6> PRIMITIVE_0 = {
|
||||
.m_vertices={
|
||||
{.m_pos={-0.5, -0.5, 1, 1}, .m_uv={0, 0}},
|
||||
{.m_pos={-0.5, -0.5, 0, 1}, .m_uv={0, 2}},
|
||||
{.m_pos={+0.5, -0.5, 1, 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 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 Graphics::Primitive<4, 6> PRIMITIVE_T = {
|
||||
.m_vertices={
|
||||
{.m_pos={-0.5, -0.5, 0, 1}, .m_uv={0, 0}},
|
||||
{.m_pos={+0.5, -0.5, 0, 1}, .m_uv={2, 0}},
|
||||
{.m_pos={-0.5, +0.5, 0, 1}, .m_uv={0, 2}},
|
||||
{.m_pos={+0.5, +0.5, 0, 1}, .m_uv={2, 2}},
|
||||
},
|
||||
.m_indices={
|
||||
0, 2, 3,
|
||||
0, 3, 1,
|
||||
},
|
||||
};
|
||||
static const 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,
|
||||
};
|
||||
|
||||
void TileRoom::remesh_room(
|
||||
Graphics::Mesh& mesh,
|
||||
const TileBase* const* neighbours,
|
||||
glm::vec<2, int> offset,
|
||||
unsigned int texid_floor,
|
||||
unsigned int texid_walls,
|
||||
unsigned int texid_ceiling,
|
||||
double height) const
|
||||
{
|
||||
auto p = PRIMITIVE_B;
|
||||
p.m_texid = texid_floor;
|
||||
p.m_offset = {offset, 0};
|
||||
mesh.add_primitive(p);
|
||||
p = PRIMITIVE_T;
|
||||
p.m_texid = texid_ceiling;
|
||||
p.m_offset = {offset, height};
|
||||
mesh.add_primitive(p);
|
||||
|
||||
for(int i = 0; i < std::size(PRIMITIVE_S); i++) {
|
||||
if(!neighbours[i]) {
|
||||
p = PRIMITIVE_S[i];
|
||||
p.m_texid = texid_walls;
|
||||
p.m_offset = {offset, 0};
|
||||
|
||||
for(Graphics::Vertex& v : p.m_vertices) {
|
||||
v.m_pos.z *= height;
|
||||
v.m_uv.y *= height;
|
||||
}
|
||||
|
||||
mesh.add_primitive(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "tile_base.hpp"
|
||||
|
||||
namespace World::Tile {
|
||||
struct TileRoom : TileBase {
|
||||
|
||||
void remesh_room(
|
||||
Graphics::Mesh& mesh,
|
||||
const TileBase* const* neighbours,
|
||||
glm::vec<2, int> offset,
|
||||
unsigned int texid_floor,
|
||||
unsigned int texid_walls,
|
||||
unsigned int texid_ceiling,
|
||||
double height) const;
|
||||
};
|
||||
};
|
||||
|
|
@ -2,37 +2,22 @@
|
|||
#include "white_brick.hpp"
|
||||
#include "tile_base.hpp"
|
||||
#include "../../graphics/texture.hpp"
|
||||
#include <iterator>
|
||||
|
||||
using World::Tile::WhiteBrick;
|
||||
using World::Tile::TileBase;
|
||||
|
||||
void WhiteBrick::update() {
|
||||
}
|
||||
|
||||
unsigned int WhiteBrick::get_texid() const {
|
||||
unsigned int WhiteBrick::get_break_texture() const {
|
||||
return Graphics::Texture::WHITE_BRICK_FLOOR;
|
||||
}
|
||||
|
||||
std::unique_ptr<World::Tile::TileBase> WhiteBrick::clone() const {
|
||||
std::unique_ptr<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);
|
||||
}
|
||||
}
|
||||
remesh_room(mesh, neighbours, offset, Graphics::Texture::WHITE_BRICK_FLOOR, Graphics::Texture::WHITE_BRICK_WALL, Graphics::Texture::WHITE_BRICK_FLOOR, 0.75);
|
||||
}
|
||||
|
||||
void WhiteBrick::render() const {
|
||||
bool WhiteBrick::can_place(const TileBase* o) const {
|
||||
return o == nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "tile_base.hpp"
|
||||
#include "tile_room.hpp"
|
||||
|
||||
namespace World::Tile {
|
||||
struct WhiteBrick : TileBase {
|
||||
void update() override;
|
||||
unsigned int get_texid() const override;
|
||||
std::unique_ptr<TileBase> clone() const override;
|
||||
struct WhiteBrick : TileRoom {
|
||||
unsigned int get_break_texture() const override;
|
||||
void remesh(Graphics::Mesh& mesh, const TileBase* const* neighbours, glm::vec<2, int> offset) const override;
|
||||
void render() const override;
|
||||
|
||||
std::unique_ptr<TileBase> clone() const override;
|
||||
bool can_place(const TileBase* o) const override;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -2,37 +2,23 @@
|
|||
#include "yellow_brick.hpp"
|
||||
#include "tile_base.hpp"
|
||||
#include "../../graphics/texture.hpp"
|
||||
#include <iterator>
|
||||
|
||||
using World::Tile::YellowBrick;
|
||||
using World::Tile::TileBase;
|
||||
|
||||
void YellowBrick::update() {
|
||||
}
|
||||
|
||||
unsigned int YellowBrick::get_texid() const {
|
||||
unsigned int YellowBrick::get_break_texture() const {
|
||||
return Graphics::Texture::YELLOW_BRICK_FLOOR;
|
||||
}
|
||||
|
||||
std::unique_ptr<World::Tile::TileBase> YellowBrick::clone() const {
|
||||
std::unique_ptr<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);
|
||||
}
|
||||
}
|
||||
remesh_room(mesh, neighbours, offset, Graphics::Texture::YELLOW_BRICK_FLOOR, Graphics::Texture::YELLOW_BRICK_WALL, Graphics::Texture::YELLOW_BRICK_FLOOR, 0.75);
|
||||
}
|
||||
|
||||
void YellowBrick::render() const {
|
||||
bool YellowBrick::can_place(const TileBase* o) const {
|
||||
return o == nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "tile_base.hpp"
|
||||
#include "tile_room.hpp"
|
||||
|
||||
namespace World::Tile {
|
||||
struct YellowBrick : TileBase {
|
||||
void update() override;
|
||||
unsigned int get_texid() const override;
|
||||
std::unique_ptr<TileBase> clone() const override;
|
||||
struct YellowBrick : TileRoom {
|
||||
unsigned int get_break_texture() const override;
|
||||
void remesh(Graphics::Mesh& mesh, const TileBase* const* neighbours, glm::vec<2, int> offset) const override;
|
||||
void render() const override;
|
||||
|
||||
std::unique_ptr<TileBase> clone() const override;
|
||||
bool can_place(const TileBase* o) const override;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue