mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-04-10 06:14:07 +08:00
feat: add block placement and destruction
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
@@ -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);
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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
24
include/Cubed/input.hpp
Normal 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();
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
9
src/input.cpp
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#include <Cubed/input.hpp>
|
||||||
|
|
||||||
|
static InputState input_state;
|
||||||
|
|
||||||
|
namespace Input {
|
||||||
|
InputState& get_input_state() {
|
||||||
|
return input_state;
|
||||||
|
}
|
||||||
|
}
|
||||||
26
src/main.cpp
26
src/main.cpp
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user