feat: add perlin noise

This commit is contained in:
2026-04-05 18:21:43 +08:00
parent 5ce0810294
commit 23affb78b5
10 changed files with 150 additions and 15 deletions

View File

@@ -1,6 +1,8 @@
#include <Cubed/gameplay/chunk.hpp>
#include <Cubed/gameplay/world.hpp>
#include <Cubed/tools/cubed_assert.hpp>
#include <Cubed/tools/log.hpp>
#include <Cubed/tools/perlin_noise.hpp>
Chunk::Chunk(World& world, ChunkPos chunk_pos) :
m_world(world),
m_chunk_pos(chunk_pos)
@@ -18,15 +20,19 @@ const std::vector<uint8_t>& Chunk::get_chunk_blocks() const{
int Chunk::get_index(int x, int y, int z) {
return x * CHUCK_SIZE * CHUCK_SIZE + y * CHUCK_SIZE + z;
if ((x * WORLD_SIZE_Y + y) * CHUCK_SIZE + z < 0 || (x * WORLD_SIZE_Y + y) * CHUCK_SIZE + z >= CHUCK_SIZE * CHUCK_SIZE * WORLD_SIZE_Y) {
Logger::error("block pos x {} y {} z {} range error", x, y, z);
CUBED_ASSERT(0);
}
return (x * WORLD_SIZE_Y + y) * CHUCK_SIZE + 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++) {
for (int y = 0; y < WORLD_SIZE_Y; y++) {
for (int z = 0; z < CHUCK_SIZE; z++) {
int world_x = x + m_chunk_pos.x * CHUCK_SIZE;
int world_z = z + m_chunk_pos.z * CHUCK_SIZE;
int world_y = y;
@@ -73,7 +79,7 @@ const std::vector<Vertex>& Chunk::get_vertex_data() const{
}
void Chunk::init_chunk() {
m_blocks.assign(CHUCK_SIZE * CHUCK_SIZE * CHUCK_SIZE, 0);
m_blocks.assign(CHUCK_SIZE * CHUCK_SIZE * WORLD_SIZE_Y, 0);
for (int x = 0; x < CHUCK_SIZE; x++) {
for (int y = 0; y < 5; y++) {
for (int z = 0; z < CHUCK_SIZE; z++) {
@@ -81,6 +87,26 @@ void Chunk::init_chunk() {
}
}
}
for (int x = 0; x < CHUCK_SIZE; x++) {
for (int z = 0; z < CHUCK_SIZE; z++) {
float world_x = static_cast<float>(x + m_chunk_pos.x * CHUCK_SIZE);
float world_z = static_cast<float>(z + m_chunk_pos.z * CHUCK_SIZE);
float noise =
0.5f * PerlinNoise::noise(world_x * 0.01f, world_z * 0.01f, 0.5f) +
0.25f * PerlinNoise::noise(world_x * 0.02f, world_z * 0.02f, 0.5f) +
0.125f * PerlinNoise::noise(world_x * 0.04f, world_z * 0.04f, 0.5f);
int y_max = height * noise;
for (int y = 5; y < y_max; y++) {
m_blocks[get_index(x, y, z)] = 1;
}
}
}
}

View File

@@ -292,6 +292,7 @@ void Player::update_move(float delta_time) {
move_distance = {direction.x * speed * delta_time, 0.0f, direction.z * speed * delta_time};
/*
if (m_move_state.up && can_up) {
y_speed = 7.5;
can_up = false;
@@ -299,6 +300,19 @@ void Player::update_move(float delta_time) {
}
y_speed += -G * delta_time;
*/
if (m_move_state.up) {
y_speed = 7.5f;
}
if (m_move_state.down) {
y_speed = -7.5f;
}
if (!m_move_state.down && !m_move_state.up) {
y_speed = 0.0f;
}
move_distance.y = y_speed * delta_time;
// y
update_y_move();
@@ -308,7 +322,7 @@ void Player::update_move(float delta_time) {
update_z_move();
if (m_player_pos.y < -15.0f) {
m_player_pos = glm::vec3(0.0f, 20.0f, 0.0f);
m_player_pos = glm::vec3(0.0f, 100.0f, 0.0f);
}
}

View File

@@ -102,7 +102,6 @@ void World::init_world() {
m_chunks.emplace(pos, Chunk(*this, pos));
}
}
Logger::info("Chunk Init Finish");
for (auto& chunk_map : m_chunks) {
auto& [chunk_pos, chunk] = chunk_map;
@@ -126,8 +125,8 @@ void World::render(const glm::mat4& mvp_matrix) {
Math::extract_frustum_planes(mvp_matrix, m_planes);
for (const auto& chunk_map : m_chunks) {
const auto& [pos, chunk] = chunk_map;
glm::vec3 center = glm::vec3(static_cast<float>(pos.x * CHUCK_SIZE) + static_cast<float>(CHUCK_SIZE / 2), static_cast<float>(CHUCK_SIZE / 2), static_cast<float>(pos.z * CHUCK_SIZE) + static_cast<float>(CHUCK_SIZE / 2));
if (is_aabb_in_frustum(center, glm::vec3(static_cast<float>(CHUCK_SIZE / 2), static_cast<float>(CHUCK_SIZE / 2), static_cast<float>(CHUCK_SIZE / 2)))) {
glm::vec3 center = glm::vec3(static_cast<float>(pos.x * CHUCK_SIZE) + static_cast<float>(CHUCK_SIZE / 2), static_cast<float>(WORLD_SIZE_Y/ 2), static_cast<float>(pos.z * CHUCK_SIZE) + static_cast<float>(CHUCK_SIZE / 2));
if (is_aabb_in_frustum(center, glm::vec3(static_cast<float>(CHUCK_SIZE / 2), static_cast<float>(WORLD_SIZE_Y / 2), static_cast<float>(CHUCK_SIZE / 2)))) {
glBindBuffer(GL_ARRAY_BUFFER, chunk.get_vbo());
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, s));
@@ -190,7 +189,7 @@ bool World::is_block(const glm::ivec3& block_pos) const{
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) {
if (x < 0 || y < 0 || z < 0 || x >= CHUCK_SIZE || y >= WORLD_SIZE_Y || z >= CHUCK_SIZE) {
return false;
}
auto id = chunk_blocks[Chunk::get_index(x, y, z)];
@@ -232,7 +231,7 @@ void World::set_block(const glm::ivec3& block_pos, unsigned id) {
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) {
if (x < 0 || y < 0 || z < 0 || x >= CHUCK_SIZE || y >= WORLD_SIZE_Y || z >= CHUCK_SIZE) {
return ;
}