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/player.cpp
src/gameplay/world.cpp
src/input.cpp
src/map_table.cpp
src/texture_manager.cpp
src/tools/shader_tools.cpp

View File

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

View File

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

View File

@@ -2,17 +2,11 @@
#include <glm/glm.hpp>
#include <Cubed/config.hpp>
#include <Cubed/gameplay/block.hpp>
#include <Cubed/input.hpp>
#include <optional>
#include <string>
struct MoveState {
bool forward = false;
bool back = false;
bool left = false;
bool right = false;
bool down = false;
bool up = false;
};
class World;
@@ -31,17 +25,17 @@ private:
glm::vec3 m_right;
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;
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:
Player(World& world, const std::string& name);
~Player();
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 MoveState& get_move_state() const;

View File

@@ -17,11 +17,12 @@ public:
~World();
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);
void init_world();
bool is_block(const glm::ivec3& block_pos) const;
void render();
void set_block(const glm::ivec3& pos, unsigned id);
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/world.hpp>
#include <Cubed/tools/log.hpp>
Chunk::Chunk(World& world, ChunkPos chunk_pos) :
m_world(world),
m_chunk_pos(chunk_pos)
@@ -21,6 +22,8 @@ int Chunk::get_index(int x, int y, int z) {
}
void Chunk::gen_vertex_data() {
m_vertexs_data.clear();
glDeleteBuffers(1, &m_vbo);
for (int x = 0; x < CHUCK_SIZE; x++) {
for (int z = 0; z < CHUCK_SIZE; z++) {
for (int y = 0; y < CHUCK_SIZE; y++) {
@@ -29,7 +32,7 @@ void Chunk::gen_vertex_data() {
int world_y = y;
const auto& block_render_data = m_world.get_block_render_data(world_x, world_y, world_z);
// air
if (block_render_data.block_id == 0) {
if (m_blocks[get_index(x, y, z)] == 0) {
continue;
}
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/world.hpp>
#include <Cubed/map_table.hpp>
#include <Cubed/tools/log.hpp>
#include <GLFW/glfw3.h>
@@ -17,8 +18,8 @@ const glm::vec3& Player::get_front() const {
return m_front;
}
const std::optional<glm::ivec3>& Player::get_look_block_pos() const {
return m_look_block_pos;
const std::optional<LookBlock>& Player::get_look_block_pos() const {
return m_look_block;
}
const glm::vec3& Player::get_player_pos() const {
@@ -29,15 +30,75 @@ const MoveState& Player::get_move_state() const {
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;
glm::ivec3 cur = glm::floor(start);
for (float t = 0.0f; t < distance; t += step) {
glm::vec3 point = start + dir * t;
block_pos = glm::floor(point);
if (m_world.is_block(block_pos)) {
int ix = cur.x;
int iy = cur.y;
int iz = cur.z;
// 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;
}
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;
}
@@ -73,11 +134,31 @@ void Player::update(float delta_time) {
*/
// calculate the block that is looked
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)) {
m_look_block_pos = std::move(block_pos);
glm::vec3 block_normal;
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 {
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;
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) {
m_player_pos = glm::vec3(0.0f, 15.0f, 0.0f);
}
}
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;
}
break;
}
}

View File

@@ -1,5 +1,6 @@
#include <Cubed/gameplay/player.hpp>
#include <Cubed/gameplay/world.hpp>
#include <Cubed/map_table.hpp>
#include <Cubed/tools/cubed_assert.hpp>
#include <Cubed/tools/cubed_hash.hpp>
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;
// block id
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
m_block_render_data.draw_face.assign(6, true);
if (x > 0 ) {
if (chunk_blocks[Chunk::get_index(x - 1, y, z)]) {
m_block_render_data.draw_face[3] = false;
}
}
if (x < CHUCK_SIZE - 1) {
if (chunk_blocks[Chunk::get_index(x + 1, y, z)]) {
m_block_render_data.draw_face[1] = false;
}
}
if (z > 0 ) {
if (chunk_blocks[Chunk::get_index(x, y, z - 1)]) {
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;
}
static const std::vector<glm::ivec3> DIR = {
glm::ivec3(0, 0, 1),
glm::ivec3(1, 0, 0),
glm::ivec3(0 ,0, -1),
glm::ivec3(-1, 0, 0),
glm::ivec3(0, 1, 0),
glm::ivec3(0, -1, 0)
};
glm::ivec3 world_pos = glm::ivec3(world_x, world_y, world_z);
for (int i = 0; i < 6; i++) {
if (is_block(world_pos + DIR[i])) {
m_block_render_data.draw_face[i] = false;
}
}
return m_block_render_data;
}
const std::optional<glm::ivec3>& World::get_look_block_pos(const std::string& name) const{
static std::optional<glm::ivec3> null_pos = std::nullopt;
const std::optional<LookBlock>& World::get_look_block_pos(const std::string& name) const{
static std::optional<LookBlock> null_look_block = std::nullopt;
auto it = m_players.find(HASH::str(name));
if (it == m_players.end()) {
LOG::error("Can't find player {}", name);
CUBED_ASSERT(0);
return null_pos;
return null_look_block;
}
return it->second.get_look_block_pos();
@@ -265,6 +113,7 @@ void World::init_world() {
}
void World::render() {
for (const auto& chunk_map : m_chunks) {
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) {
for (auto& player : m_players) {
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;
void setup_vertices(void) {
glGenVertexArrays(NUM_VAO, vao);
@@ -124,7 +126,7 @@ void display(GLFWwindow* window, double current_time) {
proj_loc = glGetUniformLocation(outline_program, "proj_matrix");
const auto& block_pos = world.get_look_block_pos("TestPlayer");
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;
glUniformMatrix4fv(mv_loc, 1, GL_FALSE, glm::value_ptr(mv_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);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glLineWidth(4.0f);
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);
}
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() {
if (!glfwInit()) {
@@ -185,6 +208,7 @@ int main() {
glfwSwapInterval(1);
glfwSetWindowSizeCallback(window, window_reshape_callback);
glfwSetKeyCallback(window, key_callback);
glfwSetMouseButtonCallback(window, mouse_button_callback);
glfwSetCursorPosCallback(window, cursor_position_callback);
MapTable::init_map();
texture_manager.init_texture();