feat: add block placement and destruction

This commit is contained in:
2026-03-14 14:37:27 +08:00
parent ec2d3c3c0c
commit 8b1579b5fd
11 changed files with 329 additions and 198 deletions

View File

@@ -50,6 +50,7 @@ add_executable(${PROJECT_NAME}
src/gameplay/chunk.cpp src/gameplay/chunk.cpp
src/gameplay/player.cpp src/gameplay/player.cpp
src/gameplay/world.cpp src/gameplay/world.cpp
src/input.cpp
src/map_table.cpp src/map_table.cpp
src/texture_manager.cpp src/texture_manager.cpp
src/tools/shader_tools.cpp src/tools/shader_tools.cpp

View File

@@ -20,4 +20,9 @@ struct BlockRenderData {
glm::vec3 pos; glm::vec3 pos;
std::vector<bool> draw_face; std::vector<bool> draw_face;
unsigned block_id; unsigned block_id;
};
struct LookBlock {
glm::ivec3 pos;
glm::ivec3 normal;
}; };

View File

@@ -14,7 +14,7 @@ private:
World& m_world; World& m_world;
// the index is a array of block id // the index is a array of block id
std::vector<uint8_t> m_blocks; std::vector<uint8_t> m_blocks;
GLuint m_vbo; GLuint m_vbo = 0;
std::vector<Vertex> m_vertexs_data; std::vector<Vertex> m_vertexs_data;
public: public:
@@ -28,5 +28,7 @@ public:
GLuint get_vbo() const; GLuint get_vbo() const;
const std::vector<Vertex>& get_vertex_data() const; const std::vector<Vertex>& get_vertex_data() const;
void init_chunk(); void init_chunk();
void set_chunk_block(int index, unsigned id);
}; };

View File

@@ -2,17 +2,11 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <Cubed/config.hpp> #include <Cubed/config.hpp>
#include <Cubed/gameplay/block.hpp>
#include <Cubed/input.hpp>
#include <optional> #include <optional>
#include <string> #include <string>
struct MoveState {
bool forward = false;
bool back = false;
bool left = false;
bool right = false;
bool down = false;
bool up = false;
};
class World; class World;
@@ -31,17 +25,17 @@ private:
glm::vec3 m_right; glm::vec3 m_right;
MoveState m_move_state; MoveState m_move_state;
std::optional<glm::ivec3> m_look_block_pos = std::nullopt; std::optional<LookBlock> m_look_block = std::nullopt;
std::string m_name; std::string m_name;
World& m_world; World& m_world;
bool ray_cast(const glm::vec3& start, const glm::vec3& dir, glm::ivec3& block_pos, float distance = 4.0f); bool ray_cast(const glm::vec3& start, const glm::vec3& dir, glm::ivec3& block_pos, glm::vec3& normal, float distance = 4.0f);
public: public:
Player(World& world, const std::string& name); Player(World& world, const std::string& name);
~Player(); ~Player();
const glm::vec3& get_front() const; const glm::vec3& get_front() const;
const std::optional<glm::ivec3>& get_look_block_pos() const; const std::optional<LookBlock>& get_look_block_pos() const;
const glm::vec3& get_player_pos() const; const glm::vec3& get_player_pos() const;
const MoveState& get_move_state() const; const MoveState& get_move_state() const;

View File

@@ -17,11 +17,12 @@ public:
~World(); ~World();
const BlockRenderData& get_block_render_data(int x, int y ,int z); const BlockRenderData& get_block_render_data(int x, int y ,int z);
const std::optional<glm::ivec3>& get_look_block_pos(const std::string& name) const; const std::optional<LookBlock>& get_look_block_pos(const std::string& name) const;
Player& get_player(const std::string& name); Player& get_player(const std::string& name);
void init_world(); void init_world();
bool is_block(const glm::ivec3& block_pos) const; bool is_block(const glm::ivec3& block_pos) const;
void render(); void render();
void set_block(const glm::ivec3& pos, unsigned id);
void update(float delta_time); void update(float delta_time);

24
include/Cubed/input.hpp Normal file
View File

@@ -0,0 +1,24 @@
#pragma once
struct MoveState {
bool forward = false;
bool back = false;
bool left = false;
bool right = false;
bool down = false;
bool up = false;
};
struct MouseState {
bool left = false;
bool right = false;
};
struct InputState {
MoveState move_state;
MouseState mouse_state;
};
namespace Input {
InputState& get_input_state();
}

View File

@@ -1,5 +1,6 @@
#include <Cubed/gameplay/chunk.hpp> #include <Cubed/gameplay/chunk.hpp>
#include <Cubed/gameplay/world.hpp> #include <Cubed/gameplay/world.hpp>
#include <Cubed/tools/log.hpp>
Chunk::Chunk(World& world, ChunkPos chunk_pos) : Chunk::Chunk(World& world, ChunkPos chunk_pos) :
m_world(world), m_world(world),
m_chunk_pos(chunk_pos) m_chunk_pos(chunk_pos)
@@ -21,6 +22,8 @@ int Chunk::get_index(int x, int y, int z) {
} }
void Chunk::gen_vertex_data() { void Chunk::gen_vertex_data() {
m_vertexs_data.clear();
glDeleteBuffers(1, &m_vbo);
for (int x = 0; x < CHUCK_SIZE; x++) { for (int x = 0; x < CHUCK_SIZE; x++) {
for (int z = 0; z < CHUCK_SIZE; z++) { for (int z = 0; z < CHUCK_SIZE; z++) {
for (int y = 0; y < CHUCK_SIZE; y++) { for (int y = 0; y < CHUCK_SIZE; y++) {
@@ -29,7 +32,7 @@ void Chunk::gen_vertex_data() {
int world_y = y; int world_y = y;
const auto& block_render_data = m_world.get_block_render_data(world_x, world_y, world_z); const auto& block_render_data = m_world.get_block_render_data(world_x, world_y, world_z);
// air // air
if (block_render_data.block_id == 0) { if (m_blocks[get_index(x, y, z)] == 0) {
continue; continue;
} }
for (int face = 0; face < 6; face++) { for (int face = 0; face < 6; face++) {
@@ -81,4 +84,11 @@ void Chunk::init_chunk() {
} }
void Chunk::set_chunk_block(int index ,unsigned id) {
m_blocks[index] = id;
glDeleteBuffers(1, &m_vbo);
gen_vertex_data();
}

View File

@@ -1,5 +1,6 @@
#include <Cubed/gameplay/player.hpp> #include <Cubed/gameplay/player.hpp>
#include <Cubed/gameplay/world.hpp> #include <Cubed/gameplay/world.hpp>
#include <Cubed/map_table.hpp>
#include <Cubed/tools/log.hpp> #include <Cubed/tools/log.hpp>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
@@ -17,8 +18,8 @@ const glm::vec3& Player::get_front() const {
return m_front; return m_front;
} }
const std::optional<glm::ivec3>& Player::get_look_block_pos() const { const std::optional<LookBlock>& Player::get_look_block_pos() const {
return m_look_block_pos; return m_look_block;
} }
const glm::vec3& Player::get_player_pos() const { const glm::vec3& Player::get_player_pos() const {
@@ -29,15 +30,75 @@ const MoveState& Player::get_move_state() const {
return m_move_state; return m_move_state;
} }
bool Player::ray_cast(const glm::vec3& start, const glm::vec3& dir,glm::ivec3& block_pos, float distance) { bool Player::ray_cast(const glm::vec3& start, const glm::vec3& front, glm::ivec3& block_pos, glm::vec3& normal, float distance) {
glm::vec3 dir = glm::normalize(front);
float step = 0.1f; float step = 0.1f;
glm::ivec3 cur = glm::floor(start); glm::ivec3 cur = glm::floor(start);
for (float t = 0.0f; t < distance; t += step) { int ix = cur.x;
glm::vec3 point = start + dir * t; int iy = cur.y;
block_pos = glm::floor(point); int iz = cur.z;
if (m_world.is_block(block_pos)) { // step direction
int step_x = (dir.x > 0) ? 1 : ((dir.x < 0) ? -1 : 0);
int step_y = (dir.y > 0) ? 1 : ((dir.y < 0) ? -1 : 0);
int step_z = (dir.z > 0) ? 1 : ((dir.z < 0) ? -1 : 0);
static const float INF = std::numeric_limits<float>::infinity();
float t_delta_x = (dir.x != 0) ? std::fabs(1.0f / dir.x) : INF;
float t_delta_y = (dir.y != 0) ? std::fabs(1.0f / dir.y) : INF;
float t_delta_z = (dir.z != 0) ? std::fabs(1.0f / dir.z) : INF;
float t_max_x, t_max_y, t_max_z;
if (dir.x > 0) {
t_max_x = (static_cast<float>(ix) + 1.0f - start.x) / dir.x;
} else if (dir.x < 0) {
t_max_x = (start.x - static_cast<float>(ix)) / (-dir.x);
} else {
t_max_x = INF;
}
if (dir.y > 0) {
t_max_y = (static_cast<float>(iy) + 1.0f - start.y) / dir.y;
} else if (dir.y < 0) {
t_max_y = (start.y - static_cast<float>(iy)) / (-dir.y);
} else {
t_max_y = INF;
}
if (dir.z > 0) {
t_max_z = (static_cast<float>(iz) + 1.0f - start.z) / dir.z;
} else if (dir.z < 0) {
t_max_z = (start.z - static_cast<float>(iz)) / (-dir.z);
} else {
t_max_z = INF;
}
float t = 0.0f;
normal = glm::vec3(0.0f, 0.0f, 0.0f);
while (t <= distance) {
if (m_world.is_block(glm::ivec3(ix, iy, iz))) {
block_pos = glm::ivec3(ix, iy, iz);
return true; return true;
} }
if (t_max_x < t_max_y && t_max_x < t_max_z) {
t = t_max_x;
t_max_x += t_delta_x;
normal = glm::vec3(-step_x, 0.0f, 0.0f);
ix += step_x;
} else if (t_max_y < t_max_z) {
t = t_max_y;
t_max_y += t_delta_y;
normal = glm::vec3(0.0f, -step_y, 0.0f);
iy += step_y;
} else {
t = t_max_z;
t_max_z += t_delta_z;
normal = glm::vec3(0.0f, 0.0f, -step_z);
iz += step_z;
}
} }
return false; return false;
} }
@@ -73,11 +134,31 @@ void Player::update(float delta_time) {
*/ */
// calculate the block that is looked // calculate the block that is looked
glm::ivec3 block_pos; glm::ivec3 block_pos;
if(ray_cast(glm::vec3(m_player_pos.x + 0.5f, (m_player_pos.y + 1.0f), m_player_pos.z + 0.5f), m_front, block_pos)) { glm::vec3 block_normal;
m_look_block_pos = std::move(block_pos); if(ray_cast(glm::vec3(m_player_pos.x + 0.5f, (m_player_pos.y + 1.0f), m_player_pos.z + 0.5f), m_front, block_pos, block_normal)) {
m_look_block = std::move(LookBlock{block_pos, glm::floor(block_normal)});
} else { } else {
m_look_block_pos = std::nullopt; m_look_block = std::nullopt;
} }
if (m_look_block != std::nullopt) {
if (Input::get_input_state().mouse_state.left) {
if (m_world.is_block(m_look_block->pos)) {
m_world.set_block(m_look_block->pos, 0);
}
Input::get_input_state().mouse_state.left = false;
}
if (Input::get_input_state().mouse_state.right) {
glm::ivec3 near_pos = m_look_block->pos + m_look_block->normal;
if (!m_world.is_block(near_pos)) {
m_world.set_block(near_pos, 1);
}
Input::get_input_state().mouse_state.right = false;
}
}
static bool should_ceil = true; static bool should_ceil = true;
if (!m_world.is_block(m_player_pos)) { if (!m_world.is_block(m_player_pos)) {
@@ -90,6 +171,9 @@ void Player::update(float delta_time) {
if (m_player_pos.y < -50.0f) { if (m_player_pos.y < -50.0f) {
m_player_pos = glm::vec3(0.0f, 15.0f, 0.0f); m_player_pos = glm::vec3(0.0f, 15.0f, 0.0f);
} }
} }
void Player::update_player_move_state(int key, int action) { void Player::update_player_move_state(int key, int action) {
@@ -142,8 +226,6 @@ void Player::update_player_move_state(int key, int action) {
m_move_state.down = false; m_move_state.down = false;
} }
break; break;
} }
} }

View File

@@ -1,5 +1,6 @@
#include <Cubed/gameplay/player.hpp> #include <Cubed/gameplay/player.hpp>
#include <Cubed/gameplay/world.hpp> #include <Cubed/gameplay/world.hpp>
#include <Cubed/map_table.hpp>
#include <Cubed/tools/cubed_assert.hpp> #include <Cubed/tools/cubed_assert.hpp>
#include <Cubed/tools/cubed_hash.hpp> #include <Cubed/tools/cubed_hash.hpp>
World::World() { World::World() {
@@ -35,189 +36,36 @@ const BlockRenderData& World::get_block_render_data(int world_x, int world_y ,in
z = world_z - chunk_z * CHUCK_SIZE; z = world_z - chunk_z * CHUCK_SIZE;
// block id // block id
m_block_render_data.block_id = chunk_blocks[Chunk::get_index(x, y, z)]; m_block_render_data.block_id = chunk_blocks[Chunk::get_index(x, y, z)];
if (m_block_render_data.block_id == 0) {
return m_block_render_data;
}
// draw_face // draw_face
m_block_render_data.draw_face.assign(6, true); m_block_render_data.draw_face.assign(6, true);
if (x > 0 ) { static const std::vector<glm::ivec3> DIR = {
if (chunk_blocks[Chunk::get_index(x - 1, y, z)]) { glm::ivec3(0, 0, 1),
m_block_render_data.draw_face[3] = false; glm::ivec3(1, 0, 0),
} glm::ivec3(0 ,0, -1),
} glm::ivec3(-1, 0, 0),
if (x < CHUCK_SIZE - 1) { glm::ivec3(0, 1, 0),
if (chunk_blocks[Chunk::get_index(x + 1, y, z)]) { glm::ivec3(0, -1, 0)
m_block_render_data.draw_face[1] = false; };
} glm::ivec3 world_pos = glm::ivec3(world_x, world_y, world_z);
} for (int i = 0; i < 6; i++) {
if (z > 0 ) { if (is_block(world_pos + DIR[i])) {
if (chunk_blocks[Chunk::get_index(x, y, z - 1)]) { m_block_render_data.draw_face[i] = false;
m_block_render_data.draw_face[2] = false;
}
}
if (z < CHUCK_SIZE - 1) {
if (chunk_blocks[Chunk::get_index(x, y, z + 1)]) {
m_block_render_data.draw_face[0] = false;
}
}
if (y > 0 ) {
if (chunk_blocks[Chunk::get_index(x, y - 1, z)]) {
m_block_render_data.draw_face[5] = false;
}
}
if (y < CHUCK_SIZE - 1) {
if (chunk_blocks[Chunk::get_index(x, y + 1, z)]) {
m_block_render_data.draw_face[4] = false;
}
}
int adjacent_chunk_x;
int adjacent_chunk_z;
int adj_world_x;
int adj_world_z;
int adjacent_x, adjacent_z;
if (x == 0) {
adj_world_x = world_x - 1;
adj_world_z = world_z;
if (adj_world_x < 0) {
adjacent_chunk_x = (adj_world_x + 1) / CHUCK_SIZE - 1;
}
if (adj_world_x >= 0) {
adjacent_chunk_x = adj_world_x / CHUCK_SIZE;
}
if (adj_world_z < 0) {
adjacent_chunk_z = (adj_world_z + 1) / CHUCK_SIZE - 1;
}
if (adj_world_z >= 0) {
adjacent_chunk_z = adj_world_z / CHUCK_SIZE;
}
auto adjacent = m_chunks.find(ChunkPos{adjacent_chunk_x, adjacent_chunk_z});
if (adjacent != m_chunks.end()) {
const auto& adjacent_chunk_blocks = it->second.get_chunk_blocks();
int x, y, z;
y = world_y;
x = world_x - 1 - adjacent_chunk_x * CHUCK_SIZE;
z = world_z - adjacent_chunk_z * CHUCK_SIZE;
if (x < 0 || y < 0 || z < 0 || Chunk::get_index(x, y, z) >= 4096 || Chunk::get_index(x, y, z) < 0) {
LOG::info("adj x {} z {}", adjacent_chunk_x, adjacent_chunk_z);
LOG::info("x {} y {} z {}, world x {} world y {} world z {} chunk x {} chunk z {}", x, y, z ,world_x, world_y, world_z, chunk_x, chunk_z);
} else
if (adjacent_chunk_blocks[Chunk::get_index(x, y, z)]) {
m_block_render_data.draw_face[3] = false;
}
}
}
if (x == CHUCK_SIZE - 1) {
adj_world_x = world_x + 1;
adj_world_z = world_z;
if (adj_world_x < 0) {
adjacent_chunk_x = (adj_world_x + 1) / CHUCK_SIZE - 1;
}
if (adj_world_x >= 0) {
adjacent_chunk_x = adj_world_x/ CHUCK_SIZE;
}
if (adj_world_z < 0) {
adjacent_chunk_z = (adj_world_z + 1) / CHUCK_SIZE - 1;
}
if (adj_world_z >= 0) {
adjacent_chunk_z = adj_world_z / CHUCK_SIZE;
}
auto adjacent = m_chunks.find(ChunkPos{adjacent_chunk_x, adjacent_chunk_z});
if (adjacent != m_chunks.end()) {
int adjacent_x, adjacent_z;
const auto& adjacent_chunk_blocks = it->second.get_chunk_blocks();
int x, y, z;
y = world_y;
x = world_x + 1 - adjacent_chunk_x * CHUCK_SIZE;
z = world_z - adjacent_chunk_z * CHUCK_SIZE;
if (x < 0 || y < 0 || z < 0 || Chunk::get_index(x, y, z) >= 4096 || Chunk::get_index(x, y, z) < 0) {
LOG::info("adj x {} z {}", adjacent_chunk_x, adjacent_chunk_z);
LOG::info("x {} y {} z {}, world x {} world y {} world z {} chunk x {} chunk z {}", x, y, z ,world_x, world_y, world_z, chunk_x, chunk_z);
} else
if (adjacent_chunk_blocks[Chunk::get_index(x, y, z)]) {
m_block_render_data.draw_face[1] = false;
}
}
}
if (z == 0) {
adj_world_x = world_x;
adj_world_z = world_z - 1;
if (adj_world_x < 0) {
adjacent_chunk_x = (adj_world_x + 1) / CHUCK_SIZE - 1;
}
if (adj_world_x >= 0) {
adjacent_chunk_x = adj_world_x / CHUCK_SIZE;
}
if (adj_world_z < 0) {
adjacent_chunk_z = (adj_world_z + 1) / CHUCK_SIZE - 1;
}
if (adj_world_z >= 0) {
adjacent_chunk_z = adj_world_z / CHUCK_SIZE;
}
auto adjacent = m_chunks.find(ChunkPos{adjacent_chunk_x, adjacent_chunk_z});
if (adjacent != m_chunks.end()) {
int adjacent_x, adjacent_z;
const auto& adjacent_chunk_blocks = it->second.get_chunk_blocks();
int x, y, z;
y = world_y;
x = world_x - adjacent_chunk_x * CHUCK_SIZE;
z = world_z - 1 - adjacent_chunk_z * CHUCK_SIZE;
if (x < 0 || y < 0 || z < 0 || Chunk::get_index(x, y, z) >= 4096 || Chunk::get_index(x, y, z) < 0) {
LOG::info("adj x {} z {}", adjacent_chunk_x, adjacent_chunk_z);
LOG::info("x {} y {} z {}, world x {} world y {} world z {} chunk x {} chunk z {}", x, y, z ,world_x, world_y, world_z, chunk_x, chunk_z);
} else
if (adjacent_chunk_blocks[Chunk::get_index(x, y, z)]) {
m_block_render_data.draw_face[2] = false;
}
}
}
if (z == CHUCK_SIZE - 1) {
adj_world_x = world_x;
adj_world_z = world_z + 1;
if (adj_world_x < 0) {
adjacent_chunk_x = (adj_world_x + 1) / CHUCK_SIZE - 1;
}
if (adj_world_x >= 0) {
adjacent_chunk_x = adj_world_x/ CHUCK_SIZE;
}
if (adj_world_z < 0) {
adjacent_chunk_z = (adj_world_z + 1) / CHUCK_SIZE - 1;
}
if (adj_world_z >= 0) {
adjacent_chunk_z = adj_world_z / CHUCK_SIZE;
}
auto adjacent = m_chunks.find(ChunkPos{adjacent_chunk_x, adjacent_chunk_z});
if (adjacent != m_chunks.end()) {
int adjacent_x, adjacent_z;
const auto& adjacent_chunk_blocks = it->second.get_chunk_blocks();
int x, y, z;
y = world_y;
x = world_x - adjacent_chunk_x * CHUCK_SIZE;
z = world_z + 1 - adjacent_chunk_z * CHUCK_SIZE;
if (x < 0 || y < 0 || z < 0 || Chunk::get_index(x, y, z) >= 4096 || Chunk::get_index(x, y, z) < 0) {
LOG::info("adj x {} z {}", adjacent_chunk_x, adjacent_chunk_z);
LOG::info("x {} y {} z {}, world x {} world y {} world z {} chunk x {} chunk z {}", x, y, z ,world_x, world_y, world_z, chunk_x, chunk_z);
} else
if (adjacent_chunk_blocks[Chunk::get_index(x, y, z)]) {
m_block_render_data.draw_face[0] = false;
}
} }
} }
return m_block_render_data; return m_block_render_data;
} }
const std::optional<glm::ivec3>& World::get_look_block_pos(const std::string& name) const{ const std::optional<LookBlock>& World::get_look_block_pos(const std::string& name) const{
static std::optional<glm::ivec3> null_pos = std::nullopt; static std::optional<LookBlock> null_look_block = std::nullopt;
auto it = m_players.find(HASH::str(name)); auto it = m_players.find(HASH::str(name));
if (it == m_players.end()) { if (it == m_players.end()) {
LOG::error("Can't find player {}", name); LOG::error("Can't find player {}", name);
CUBED_ASSERT(0); CUBED_ASSERT(0);
return null_pos; return null_look_block;
} }
return it->second.get_look_block_pos(); return it->second.get_look_block_pos();
@@ -265,6 +113,7 @@ void World::init_world() {
} }
void World::render() { void World::render() {
for (const auto& chunk_map : m_chunks) { for (const auto& chunk_map : m_chunks) {
const auto& [pos, chunk] = chunk_map; const auto& [pos, chunk] = chunk_map;
@@ -325,6 +174,136 @@ bool World::is_block(const glm::ivec3& block_pos) const{
} }
} }
void World::set_block(const glm::ivec3& block_pos, unsigned id) {
int chunk_x, chunk_z;
int world_x, world_y, world_z;
world_x = block_pos.x;
world_y = block_pos.y;
world_z = block_pos.z;
if (world_x < 0) {
chunk_x = (world_x + 1) / CHUCK_SIZE - 1;
}
if (world_x >= 0) {
chunk_x = world_x / CHUCK_SIZE;
}
if (world_z < 0) {
chunk_z = (world_z + 1) / CHUCK_SIZE - 1;
}
if (world_z >= 0) {
chunk_z = world_z / CHUCK_SIZE;
}
auto it = m_chunks.find(ChunkPos{chunk_x, chunk_z});
if (it == m_chunks.end()) {
return ;
}
int x, y, z;
y = world_y;
x = world_x - chunk_x * CHUCK_SIZE;
z = world_z - chunk_z * CHUCK_SIZE;
if (x < 0 || y < 0 || z < 0 || x >= CHUCK_SIZE || y >= CHUCK_SIZE || z >= CHUCK_SIZE) {
return ;
}
it->second.set_chunk_block(Chunk::get_index(x, y, z), id);
int adjacent_chunk_x;
int adjacent_chunk_z;
int adj_world_x;
int adj_world_z;
if (x == 0) {
adj_world_x = world_x - 1;
adj_world_z = world_z;
if (adj_world_x < 0) {
adjacent_chunk_x = (adj_world_x + 1) / CHUCK_SIZE - 1;
}
if (adj_world_x >= 0) {
adjacent_chunk_x = adj_world_x / CHUCK_SIZE;
}
if (adj_world_z < 0) {
adjacent_chunk_z = (adj_world_z + 1) / CHUCK_SIZE - 1;
}
if (adj_world_z >= 0) {
adjacent_chunk_z = adj_world_z / CHUCK_SIZE;
}
auto adjacent = m_chunks.find(ChunkPos{adjacent_chunk_x, adjacent_chunk_z});
if (adjacent != m_chunks.end()) {
adjacent->second.gen_vertex_data();
}
}
if (x == CHUCK_SIZE - 1) {
adj_world_x = world_x + 1;
adj_world_z = world_z;
if (adj_world_x < 0) {
adjacent_chunk_x = (adj_world_x + 1) / CHUCK_SIZE - 1;
}
if (adj_world_x >= 0) {
adjacent_chunk_x = adj_world_x/ CHUCK_SIZE;
}
if (adj_world_z < 0) {
adjacent_chunk_z = (adj_world_z + 1) / CHUCK_SIZE - 1;
}
if (adj_world_z >= 0) {
adjacent_chunk_z = adj_world_z / CHUCK_SIZE;
}
auto adjacent = m_chunks.find(ChunkPos{adjacent_chunk_x, adjacent_chunk_z});
if (adjacent != m_chunks.end()) {
adjacent->second.gen_vertex_data();
}
}
if (z == 0) {
adj_world_x = world_x;
adj_world_z = world_z - 1;
if (adj_world_x < 0) {
adjacent_chunk_x = (adj_world_x + 1) / CHUCK_SIZE - 1;
}
if (adj_world_x >= 0) {
adjacent_chunk_x = adj_world_x / CHUCK_SIZE;
}
if (adj_world_z < 0) {
adjacent_chunk_z = (adj_world_z + 1) / CHUCK_SIZE - 1;
}
if (adj_world_z >= 0) {
adjacent_chunk_z = adj_world_z / CHUCK_SIZE;
}
auto adjacent = m_chunks.find(ChunkPos{adjacent_chunk_x, adjacent_chunk_z});
if (adjacent != m_chunks.end()) {
adjacent->second.gen_vertex_data();
}
}
if (z == CHUCK_SIZE - 1) {
adj_world_x = world_x;
adj_world_z = world_z + 1;
if (adj_world_x < 0) {
adjacent_chunk_x = (adj_world_x + 1) / CHUCK_SIZE - 1;
}
if (adj_world_x >= 0) {
adjacent_chunk_x = adj_world_x/ CHUCK_SIZE;
}
if (adj_world_z < 0) {
adjacent_chunk_z = (adj_world_z + 1) / CHUCK_SIZE - 1;
}
if (adj_world_z >= 0) {
adjacent_chunk_z = adj_world_z / CHUCK_SIZE;
}
auto adjacent = m_chunks.find(ChunkPos{adjacent_chunk_x, adjacent_chunk_z});
if (adjacent != m_chunks.end()) {
adjacent->second.gen_vertex_data();
}
}
}
void World::update(float delta_time) { void World::update(float delta_time) {
for (auto& player : m_players) { for (auto& player : m_players) {
player.second.update(delta_time); player.second.update(delta_time);

9
src/input.cpp Normal file
View File

@@ -0,0 +1,9 @@
#include <Cubed/input.hpp>
static InputState input_state;
namespace Input {
InputState& get_input_state() {
return input_state;
}
}

View File

@@ -36,6 +36,8 @@ World world;
GLuint outline_vbo, outline_indices_vbo; GLuint outline_vbo, outline_indices_vbo;
void setup_vertices(void) { void setup_vertices(void) {
glGenVertexArrays(NUM_VAO, vao); glGenVertexArrays(NUM_VAO, vao);
@@ -124,7 +126,7 @@ void display(GLFWwindow* window, double current_time) {
proj_loc = glGetUniformLocation(outline_program, "proj_matrix"); proj_loc = glGetUniformLocation(outline_program, "proj_matrix");
const auto& block_pos = world.get_look_block_pos("TestPlayer"); const auto& block_pos = world.get_look_block_pos("TestPlayer");
if (block_pos != std::nullopt) { if (block_pos != std::nullopt) {
m_mat = glm::translate(glm::mat4(1.0f), glm::vec3(block_pos.value())); m_mat = glm::translate(glm::mat4(1.0f), glm::vec3(block_pos.value().pos));
mv_mat = v_mat * m_mat; mv_mat = v_mat * m_mat;
glUniformMatrix4fv(mv_loc, 1, GL_FALSE, glm::value_ptr(mv_mat)); glUniformMatrix4fv(mv_loc, 1, GL_FALSE, glm::value_ptr(mv_mat));
glUniformMatrix4fv(proj_loc, 1 ,GL_FALSE, glm::value_ptr(p_mat)); glUniformMatrix4fv(proj_loc, 1 ,GL_FALSE, glm::value_ptr(p_mat));
@@ -136,6 +138,7 @@ void display(GLFWwindow* window, double current_time) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, outline_indices_vbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, outline_indices_vbo);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL); glDepthFunc(GL_LEQUAL);
glLineWidth(4.0f);
glDrawElements(GL_LINES, 24, GL_UNSIGNED_INT, 0); glDrawElements(GL_LINES, 24, GL_UNSIGNED_INT, 0);
} }
@@ -163,6 +166,26 @@ void key_callback(GLFWwindow* window, int key, int scancode, int action, int mod
world.get_player("TestPlayer").update_player_move_state(key, action); world.get_player("TestPlayer").update_player_move_state(key, action);
} }
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) {
switch (button) {
case GLFW_MOUSE_BUTTON_LEFT:
if (action == GLFW_PRESS) {
Input::get_input_state().mouse_state.left = true;
}
if (action == GLFW_RELEASE) {
Input::get_input_state().mouse_state.left = false;
}
break;
case GLFW_MOUSE_BUTTON_RIGHT:
if (action == GLFW_PRESS) {
Input::get_input_state().mouse_state.right = true;
}
if (action == GLFW_RELEASE) {
Input::get_input_state().mouse_state.right = false;
}
break;
}
}
int main() { int main() {
if (!glfwInit()) { if (!glfwInit()) {
@@ -185,6 +208,7 @@ int main() {
glfwSwapInterval(1); glfwSwapInterval(1);
glfwSetWindowSizeCallback(window, window_reshape_callback); glfwSetWindowSizeCallback(window, window_reshape_callback);
glfwSetKeyCallback(window, key_callback); glfwSetKeyCallback(window, key_callback);
glfwSetMouseButtonCallback(window, mouse_button_callback);
glfwSetCursorPosCallback(window, cursor_position_callback); glfwSetCursorPosCallback(window, cursor_position_callback);
MapTable::init_map(); MapTable::init_map();
texture_manager.init_texture(); texture_manager.init_texture();