mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-04-10 06:14:07 +08:00
feat: add frustum culling
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
#include <Cubed/map_table.hpp>
|
||||
#include <Cubed/tools/cubed_assert.hpp>
|
||||
#include <Cubed/tools/cubed_hash.hpp>
|
||||
#include <Cubed/tools/math_tools.hpp>
|
||||
World::World() {
|
||||
|
||||
}
|
||||
@@ -123,26 +124,43 @@ void World::init_world() {
|
||||
m_players.emplace(HASH::str("TestPlayer"), Player(*this, "TestPlayer"));
|
||||
}
|
||||
|
||||
void World::render() {
|
||||
|
||||
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)))) {
|
||||
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));
|
||||
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, layer));
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, chunk.get_vertex_data().size() * 3);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
}
|
||||
|
||||
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));
|
||||
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, layer));
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, chunk.get_vertex_data().size() * 3);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
bool World::is_aabb_in_frustum(const glm::vec3& center, const glm::vec3& half_extents) {
|
||||
for (const auto& plane : m_planes) {
|
||||
// distance
|
||||
float d = glm::dot(glm::vec3(plane), center) + plane.w;
|
||||
float r = half_extents.x * std::abs(plane.x) +
|
||||
half_extents.y * std::abs(plane.y) +
|
||||
half_extents.z * std::abs(plane.z);
|
||||
if (d + r < 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool World::is_block(const glm::ivec3& block_pos) const{
|
||||
int chunk_x, chunk_z;
|
||||
int world_x, world_y, world_z;
|
||||
|
||||
@@ -24,7 +24,7 @@ GLuint vao[NUM_VAO];
|
||||
GLuint mv_loc, proj_loc;
|
||||
int width ,height;
|
||||
float aspect;
|
||||
glm::mat4 p_mat, v_mat, m_mat, mv_mat;
|
||||
glm::mat4 p_mat, v_mat, m_mat, mv_mat, mvp_mat;
|
||||
float inc = 0.01f;
|
||||
float tf = 0.0f;
|
||||
double last_time = glfwGetTime();
|
||||
@@ -183,8 +183,8 @@ void display(GLFWwindow* window, double current_time) {
|
||||
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));
|
||||
|
||||
world.render();
|
||||
mvp_mat = p_mat * mv_mat;
|
||||
world.render(mvp_mat);
|
||||
|
||||
render_outline();
|
||||
|
||||
|
||||
29
src/tools/math_tools.cpp
Normal file
29
src/tools/math_tools.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#include <Cubed/tools/math_tools.hpp>
|
||||
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
namespace Math {
|
||||
void extract_frustum_planes(const glm::mat4& mvp_matrix, std::vector<glm::vec4>& planes) {
|
||||
if (planes.size() != 6) {
|
||||
planes.resize(6);
|
||||
}
|
||||
|
||||
const float* m = glm::value_ptr(mvp_matrix);
|
||||
|
||||
// left plane
|
||||
planes[0] = glm::vec4(m[3] + m[0], m[7] + m[4], m[11] + m[8], m[15] + m[12]);
|
||||
// right plane
|
||||
planes[1] = glm::vec4(m[3] - m[0], m[7] - m[4], m[11] - m[8], m[15] - m[12]);
|
||||
// bottom plane
|
||||
planes[2] = glm::vec4(m[3] + m[1], m[7] + m[5], m[11] + m[9], m[15] + m[13]);
|
||||
// top plane
|
||||
planes[3] = glm::vec4(m[3] - m[1], m[7] - m[5], m[11] - m[9], m[15] - m[13]);
|
||||
// near plane
|
||||
planes[4] = glm::vec4(m[3] + m[2], m[7] + m[6], m[11] + m[10], m[15] + m[14]);
|
||||
// far plane
|
||||
planes[5] = glm::vec4(m[3] - m[2], m[7] - m[6], m[11] - m[10], m[15] - m[14]);
|
||||
|
||||
for (auto& p : planes) {
|
||||
p = glm::normalize(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user