refactor: chunk render (#15)

* refactor(renderer): centralize VAO setup and rename init_underwater

* refactor(gameplay): replace VBO with VAO for vertex data

* fix(renderer): move depth test enable to world rendering

The `glEnable(GL_DEPTH_TEST)` call was incorrectly placed in the general `render()` function, affecting UI and text rendering. Moved it to the start of the world rendering loop to ensure depth testing is only active during 3D world pass.
This commit is contained in:
zhenyan121
2026-06-11 14:58:39 +08:00
committed by GitHub
parent d0bc8d627f
commit bac3df801b
8 changed files with 136 additions and 118 deletions

View File

@@ -101,16 +101,16 @@ public:
const std::array<const std::vector<BlockType>*, 4>& neighbor_block); const std::array<const std::vector<BlockType>*, 4>& neighbor_block);
void upload_to_gpu(); void upload_to_gpu();
GLuint get_normal_vbo() const; GLuint get_normal_vao() const;
size_t get_normal_vertices_sum() const; size_t get_normal_vertices_sum() const;
GLuint get_cross_vbo() const; GLuint get_cross_vao() const;
size_t get_cross_vertices_sum() const; size_t get_cross_vertices_sum() const;
GLuint get_normal_discard_vbo() const; GLuint get_normal_discard_vao() const;
size_t get_normal_discard_vertices_sum() const; size_t get_normal_discard_vertices_sum() const;
GLuint get_normal_blend_vbo() const; GLuint get_normal_blend_vao() const;
size_t get_normal_blend_vertices_sum() const; size_t get_normal_blend_vertices_sum() const;
bool is_dirty() const; bool is_dirty() const;

View File

@@ -9,6 +9,7 @@ class World;
struct VertexData { struct VertexData {
std::vector<Vertex> m_vertices; std::vector<Vertex> m_vertices;
GLuint m_vbo = 0; GLuint m_vbo = 0;
GLuint m_vao = 0;
std::atomic<std::size_t> m_sum{0}; std::atomic<std::size_t> m_sum{0};
World& m_world; World& m_world;
VertexData(World& world); VertexData(World& world);

View File

@@ -15,13 +15,13 @@
namespace Cubed { namespace Cubed {
struct ChunkRenderSnapshot { struct ChunkRenderSnapshot {
GLuint normal_vbo; GLuint normal_vao;
size_t normal_vertices_count; size_t normal_vertices_count;
GLuint cross_vbo; GLuint cross_vao;
size_t cross_vertices_count; size_t cross_vertices_count;
GLuint normal_discard_vbo; GLuint normal_discard_vao;
size_t normal_discard_vertices_count; size_t normal_discard_vertices_count;
GLuint normal_blend_vbo; GLuint normal_blend_vao;
size_t normal_blend_vertices_count; size_t normal_blend_vertices_count;
glm::vec3 center; glm::vec3 center;
glm::vec3 half_extents; glm::vec3 half_extents;
@@ -47,8 +47,10 @@ private:
std::mutex m_gen_signal_mutex; std::mutex m_gen_signal_mutex;
std::mutex m_new_chunk_queue_mutex; std::mutex m_new_chunk_queue_mutex;
std::mutex m_delete_vbo_mutex; std::mutex m_delete_vbo_mutex;
std::mutex m_delete_vao_mutex;
std::mutex m_gen_player_pos_mutex; std::mutex m_gen_player_pos_mutex;
std::vector<GLuint> m_pending_delete_vbo; std::vector<GLuint> m_pending_delete_vbo;
std::vector<GLuint> m_pending_delete_vao;
std::condition_variable m_gen_cv; std::condition_variable m_gen_cv;
std::atomic<bool> m_gen_running{false}; std::atomic<bool> m_gen_running{false};
std::atomic<bool> m_need_gen_chunk{false}; std::atomic<bool> m_need_gen_chunk{false};
@@ -104,7 +106,7 @@ public:
void update(float delta_time); void update(float delta_time);
void push_delete_vbo(GLuint vbo); void push_delete_vbo(GLuint vbo);
void push_delete_vao(GLuint vao);
void hot_reload(); void hot_reload();
void rebuild_world(); void rebuild_world();

View File

@@ -67,10 +67,18 @@ private:
glm::mat4 m_ui_proj; glm::mat4 m_ui_proj;
glm::mat4 m_ui_m_matrix; glm::mat4 m_ui_m_matrix;
std::unordered_map<std::size_t, Shader> m_shaders; std::unordered_map<std::size_t, Shader> m_shaders;
/*
0 - quad vao
1 - sky vao
2 - outline vao
3 - ui vao
4 - text vao
*/
std::vector<GLuint> m_vao; std::vector<GLuint> m_vao;
std::vector<Vertex2D> m_ui; std::vector<Vertex2D> m_ui;
void init_underwater(); void init_quad();
void init_text(); void init_text();
void render_outline(); void render_outline();

View File

@@ -123,7 +123,7 @@ void Chunk::gen_vertex_data(
m_is_on_gen_vertex_data = false; m_is_on_gen_vertex_data = false;
} }
GLuint Chunk::get_normal_vbo() const { return m_vertex_data[0].m_vbo; } GLuint Chunk::get_normal_vao() const { return m_vertex_data[0].m_vao; }
size_t Chunk::get_normal_vertices_sum() const { size_t Chunk::get_normal_vertices_sum() const {
if (m_vertex_data[0].m_sum == 0) { if (m_vertex_data[0].m_sum == 0) {
@@ -132,17 +132,17 @@ size_t Chunk::get_normal_vertices_sum() const {
return m_vertex_data[0].m_sum.load(); return m_vertex_data[0].m_sum.load();
} }
GLuint Chunk::get_cross_vbo() const { return m_vertex_data[1].m_vbo; } GLuint Chunk::get_cross_vao() const { return m_vertex_data[1].m_vao; }
size_t Chunk::get_cross_vertices_sum() const { size_t Chunk::get_cross_vertices_sum() const {
return m_vertex_data[1].m_sum.load(); return m_vertex_data[1].m_sum.load();
} }
GLuint Chunk::get_normal_discard_vbo() const { return m_vertex_data[2].m_vbo; } GLuint Chunk::get_normal_discard_vao() const { return m_vertex_data[2].m_vao; }
size_t Chunk::get_normal_discard_vertices_sum() const { size_t Chunk::get_normal_discard_vertices_sum() const {
return m_vertex_data[2].m_sum.load(); return m_vertex_data[2].m_sum.load();
} }
GLuint Chunk::get_normal_blend_vbo() const { return m_vertex_data[3].m_vbo; } GLuint Chunk::get_normal_blend_vao() const { return m_vertex_data[3].m_vao; }
size_t Chunk::get_normal_blend_vertices_sum() const { size_t Chunk::get_normal_blend_vertices_sum() const {
return m_vertex_data[3].m_sum.load(); return m_vertex_data[3].m_sum.load();
} }

View File

@@ -8,12 +8,16 @@ VertexData::~VertexData() {
if (m_vbo != 0) { if (m_vbo != 0) {
m_world.push_delete_vbo(m_vbo); m_world.push_delete_vbo(m_vbo);
} }
if (m_vao != 0) {
m_world.push_delete_vao(m_vao);
}
} }
VertexData::VertexData(VertexData&& o) noexcept VertexData::VertexData(VertexData&& o) noexcept
: m_vertices(std::move(o.m_vertices)), m_vbo(o.m_vbo), : m_vertices(std::move(o.m_vertices)), m_vbo(o.m_vbo), m_vao(o.m_vao),
m_sum(o.m_sum.load()), m_world(o.m_world) { m_sum(o.m_sum.load()), m_world(o.m_world) {
o.m_vbo = 0; o.m_vbo = 0;
o.m_sum = 0; o.m_sum = 0;
o.m_vao = 0;
} }
VertexData& VertexData::operator=(VertexData&& o) noexcept { VertexData& VertexData::operator=(VertexData&& o) noexcept {
m_vbo = o.m_vbo; m_vbo = o.m_vbo;
@@ -21,18 +25,36 @@ VertexData& VertexData::operator=(VertexData&& o) noexcept {
m_sum = o.m_sum.load(); m_sum = o.m_sum.load();
o.m_sum = 0; o.m_sum = 0;
m_vertices = std::move(o.m_vertices); m_vertices = std::move(o.m_vertices);
m_vao = o.m_vao;
o.m_vao = 0;
return *this; return *this;
} }
void VertexData::upload() { void VertexData::upload() {
if (m_vertices.size() == 0) { if (m_vertices.size() == 0) {
return; return;
} }
if (m_vao == 0) {
glGenVertexArrays(1, &m_vao);
}
if (m_vbo == 0) { if (m_vbo == 0) {
glGenBuffers(1, &m_vbo); glGenBuffers(1, &m_vbo);
} }
glBindVertexArray(m_vao);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo); glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, m_vertices.size() * sizeof(Vertex), glBufferData(GL_ARRAY_BUFFER, m_vertices.size() * sizeof(Vertex),
m_vertices.data(), GL_DYNAMIC_DRAW); m_vertices.data(), GL_DYNAMIC_DRAW);
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);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
} }
void VertexData::update_sum() { m_sum = m_vertices.size(); } void VertexData::update_sum() { m_sum = m_vertices.size(); }

View File

@@ -24,6 +24,13 @@ World::~World() {
} }
m_pending_delete_vbo.clear(); m_pending_delete_vbo.clear();
} }
{
std::lock_guard lk(m_delete_vao_mutex);
for (auto x : m_pending_delete_vao) {
glDeleteVertexArrays(1, &x);
}
m_pending_delete_vao.clear();
}
} }
bool World::can_move(const AABB& player_box) const { return true; } bool World::can_move(const AABB& player_box) const { return true; }
@@ -790,6 +797,15 @@ void World::update(float delta_time) {
} }
m_pending_delete_vbo.clear(); m_pending_delete_vbo.clear();
} }
{
std::lock_guard lk(m_delete_vao_mutex);
for (auto x : m_pending_delete_vao) {
glDeleteVertexArrays(1, &x);
}
m_pending_delete_vao.clear();
}
{ {
std::scoped_lock lk(m_chunks_mutex, m_new_chunk_queue_mutex); std::scoped_lock lk(m_chunks_mutex, m_new_chunk_queue_mutex);
m_new_chunk.clear(); m_new_chunk.clear();
@@ -837,11 +853,11 @@ void World::update(float delta_time) {
chunk.upload_to_gpu(); chunk.upload_to_gpu();
} }
m_render_snapshots.push_back( m_render_snapshots.push_back(
{chunk.get_normal_vbo(), chunk.get_normal_vertices_sum(), {chunk.get_normal_vao(), chunk.get_normal_vertices_sum(),
chunk.get_cross_vbo(), chunk.get_cross_vertices_sum(), chunk.get_cross_vao(), chunk.get_cross_vertices_sum(),
chunk.get_normal_discard_vbo(), chunk.get_normal_discard_vao(),
chunk.get_normal_discard_vertices_sum(), chunk.get_normal_discard_vertices_sum(),
chunk.get_normal_blend_vbo(), chunk.get_normal_blend_vao(),
chunk.get_normal_blend_vertices_sum(), chunk.get_normal_blend_vertices_sum(),
glm::vec3(static_cast<float>(pos.x * CHUNK_SIZE) + glm::vec3(static_cast<float>(pos.x * CHUNK_SIZE) +
static_cast<float>(CHUNK_SIZE / 2), static_cast<float>(CHUNK_SIZE / 2),
@@ -861,6 +877,11 @@ void World::push_delete_vbo(GLuint vbo) {
m_pending_delete_vbo.push_back(vbo); m_pending_delete_vbo.push_back(vbo);
} }
void World::push_delete_vao(GLuint vao) {
std::lock_guard lk(m_delete_vao_mutex);
m_pending_delete_vao.push_back(vao);
}
void World::hot_reload() { void World::hot_reload() {
auto& config = Config::get(); auto& config = Config::get();
int dist = config.get<int>("world.rendering_distance"); int dist = config.get<int>("world.rendering_distance");

View File

@@ -106,20 +106,28 @@ void Renderer::init() {
m_vao.resize(NUM_VAO); m_vao.resize(NUM_VAO);
glGenVertexArrays(NUM_VAO, m_vao.data()); glGenVertexArrays(NUM_VAO, m_vao.data());
glBindVertexArray(0); glBindVertexArray(0);
glGenBuffers(1, &m_outline_vbo);
glBindVertexArray(m_vao[2]);
glGenBuffers(1, &m_outline_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_outline_vbo); glBindBuffer(GL_ARRAY_BUFFER, m_outline_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(CUBE_VER), CUBE_VER, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(CUBE_VER), CUBE_VER, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glGenBuffers(1, &m_outline_indices_vbo); glGenBuffers(1, &m_outline_indices_vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_outline_indices_vbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_outline_indices_vbo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(OUTLINE_CUBE_INDICES), glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(OUTLINE_CUBE_INDICES),
OUTLINE_CUBE_INDICES, GL_STATIC_DRAW); OUTLINE_CUBE_INDICES, GL_STATIC_DRAW);
glBindVertexArray(m_vao[1]);
glGenBuffers(1, &m_sky_vbo); glGenBuffers(1, &m_sky_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_sky_vbo); glBindBuffer(GL_ARRAY_BUFFER, m_sky_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(VERTICES_POS), VERTICES_POS, glBufferData(GL_ARRAY_BUFFER, sizeof(VERTICES_POS), VERTICES_POS,
GL_STATIC_DRAW); GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindVertexArray(m_vao[3]);
glGenBuffers(1, &m_ui_vbo); glGenBuffers(1, &m_ui_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_ui_vbo); glBindBuffer(GL_ARRAY_BUFFER, m_ui_vbo);
@@ -132,13 +140,23 @@ void Renderer::init() {
glBufferData(GL_ARRAY_BUFFER, m_ui.size() * sizeof(Vertex2D), m_ui.data(), glBufferData(GL_ARRAY_BUFFER, m_ui.size() * sizeof(Vertex2D), m_ui.data(),
GL_STATIC_DRAW); GL_STATIC_DRAW);
glGenBuffers(1, &m_text_vbo); glBindBuffer(GL_ARRAY_BUFFER, m_ui_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_text_vbo); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void*)0);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6 * 4, NULL, GL_DYNAMIC_DRAW); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D),
glBindBuffer(GL_ARRAY_BUFFER, 0); (void*)offsetof(Vertex2D, s));
init_underwater(); glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex2D),
(void*)offsetof(Vertex2D, layer));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
init_quad();
init_text(); init_text();
hot_reload(); hot_reload();
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
} }
const Shader& Renderer::get_shader(const std::string& name) const { const Shader& Renderer::get_shader(const std::string& name) const {
@@ -147,15 +165,27 @@ const Shader& Renderer::get_shader(const std::string& name) const {
return it->second; return it->second;
} }
void Renderer::init_underwater() { void Renderer::init_quad() {
glBindVertexArray(m_vao[0]);
glGenBuffers(1, &m_quad_vbo); glGenBuffers(1, &m_quad_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_quad_vbo); glBindBuffer(GL_ARRAY_BUFFER, m_quad_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(QUAD_VERTICES), QUAD_VERTICES, glBufferData(GL_ARRAY_BUFFER, sizeof(QUAD_VERTICES), QUAD_VERTICES,
GL_STATIC_DRAW); GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float),
(void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float),
(void*)(2 * sizeof(float)));
} }
void Renderer::init_text() { void Renderer::init_text() {
glBindVertexArray(m_vao[4]);
glGenBuffers(1, &m_text_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_text_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
const auto& shader = get_shader("text"); const auto& shader = get_shader("text");
Text::set_loc(shader); Text::set_loc(shader);
DebugCollector::get().init_text(); DebugCollector::get().init_text();
@@ -163,14 +193,12 @@ void Renderer::init_text() {
void Renderer::render() { void Renderer::render() {
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
glClearColor(0.0, 0.0, 0.0, 1.0); glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArray(m_vao[0]);
render_sky(); render_sky();
glBindVertexArray(m_vao[1]);
render_world(); render_world();
glBindVertexArray(m_vao[2]);
render_outline(); render_outline();
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
@@ -178,15 +206,10 @@ void Renderer::render() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0); glClearColor(0.0f, 0.0f, 0.0f, 1.0);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(m_vao[3]);
render_underwater(); render_underwater();
glEnable(GL_DEPTH_TEST);
glBindVertexArray(m_vao[4]);
render_ui(); render_ui();
glBindVertexArray(m_vao[5]);
render_text(); render_text();
glBindVertexArray(0);
render_dev_panel(); render_dev_panel();
} }
@@ -210,11 +233,8 @@ void Renderer::render_outline() {
glUniformMatrix4fv(m_mv_loc, 1, GL_FALSE, glm::value_ptr(m_mv_mat)); glUniformMatrix4fv(m_mv_loc, 1, GL_FALSE, glm::value_ptr(m_mv_mat));
glUniformMatrix4fv(m_proj_loc, 1, GL_FALSE, glm::value_ptr(m_p_mat)); glUniformMatrix4fv(m_proj_loc, 1, GL_FALSE, glm::value_ptr(m_p_mat));
glBindBuffer(GL_ARRAY_BUFFER, m_outline_vbo); glBindVertexArray(m_vao[2]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_outline_indices_vbo);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL); glDepthFunc(GL_LEQUAL);
glLineWidth(4.0f); glLineWidth(4.0f);
@@ -238,9 +258,7 @@ void Renderer::render_sky() {
glUniformMatrix4fv(m_mv_loc, 1, GL_FALSE, glm::value_ptr(m_mv_mat)); glUniformMatrix4fv(m_mv_loc, 1, GL_FALSE, glm::value_ptr(m_mv_mat));
glUniformMatrix4fv(m_proj_loc, 1, GL_FALSE, glm::value_ptr(m_p_mat)); glUniformMatrix4fv(m_proj_loc, 1, GL_FALSE, glm::value_ptr(m_p_mat));
glBindBuffer(GL_ARRAY_BUFFER, m_sky_vbo); glBindVertexArray(m_vao[1]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
@@ -249,11 +267,18 @@ void Renderer::render_sky() {
} }
void Renderer::render_text() { void Renderer::render_text() {
glBindVertexArray(m_vao[4]);
const auto& shader = get_shader("text"); const auto& shader = get_shader("text");
shader.use(); shader.use();
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
m_proj_loc = shader.loc("projection"); m_proj_loc = shader.loc("projection");
glUniformMatrix4fv(m_proj_loc, 1, GL_FALSE, glm::value_ptr(m_ui_proj)); glUniformMatrix4fv(m_proj_loc, 1, GL_FALSE, glm::value_ptr(m_ui_proj));
@@ -279,23 +304,13 @@ void Renderer::render_ui() {
glUniformMatrix4fv(m_mv_loc, 1, GL_FALSE, glm::value_ptr(m_ui_m_matrix)); glUniformMatrix4fv(m_mv_loc, 1, GL_FALSE, glm::value_ptr(m_ui_m_matrix));
glUniformMatrix4fv(m_proj_loc, 1, GL_FALSE, glm::value_ptr(m_ui_proj)); glUniformMatrix4fv(m_proj_loc, 1, GL_FALSE, glm::value_ptr(m_ui_proj));
glBindBuffer(GL_ARRAY_BUFFER, m_ui_vbo); glBindVertexArray(m_vao[3]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void*)0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D),
(void*)offsetof(Vertex2D, s));
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex2D),
(void*)offsetof(Vertex2D, layer));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture_manager.get_ui_array()); glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture_manager.get_ui_array());
glDrawArrays(GL_TRIANGLES, 0, 6); glDrawArrays(GL_TRIANGLES, 0, 6);
Tools::check_opengl_error(); Tools::check_opengl_error();
glBindBuffer(GL_ARRAY_BUFFER, 0);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
} }
@@ -303,13 +318,8 @@ void Renderer::render_ui() {
void Renderer::render_underwater() { void Renderer::render_underwater() {
const auto& shader = get_shader("under_water"); const auto& shader = get_shader("under_water");
shader.use(); shader.use();
glBindBuffer(GL_ARRAY_BUFFER, m_quad_vbo);
glEnableVertexAttribArray(0); glBindVertexArray(m_vao[0]);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float),
(void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float),
(void*)(2 * sizeof(float)));
glUniform1i(shader.loc("u_sceneTexture"), 0); glUniform1i(shader.loc("u_sceneTexture"), 0);
glUniform1f(shader.loc("u_time"), glfwGetTime()); glUniform1f(shader.loc("u_time"), glfwGetTime());
@@ -423,6 +433,7 @@ void Renderer::render_world() {
m_mv_loc = normal_block_shader.loc("mv_matrix"); m_mv_loc = normal_block_shader.loc("mv_matrix");
m_proj_loc = normal_block_shader.loc("proj_matrix"); m_proj_loc = normal_block_shader.loc("proj_matrix");
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
m_m_mat = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.0f)); m_m_mat = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.0f));
@@ -439,27 +450,17 @@ void Renderer::render_world() {
Math::extract_frustum_planes(m_mvp_mat, m_planes); Math::extract_frustum_planes(m_mvp_mat, m_planes);
int rendered_sum = 0; int rendered_sum = 0;
glEnable(GL_DEPTH_TEST);
for (const auto& snapshot : m_render_snapshots) { for (const auto& snapshot : m_render_snapshots) {
if (Math::is_aabb_in_frustum(snapshot.center, snapshot.half_extents, if (Math::is_aabb_in_frustum(snapshot.center, snapshot.half_extents,
m_planes)) { m_planes)) {
glBindTexture(GL_TEXTURE_2D_ARRAY, glBindTexture(GL_TEXTURE_2D_ARRAY,
m_texture_manager.get_texture_array()); m_texture_manager.get_texture_array());
glBindBuffer(GL_ARRAY_BUFFER, snapshot.normal_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); glBindVertexArray(snapshot.normal_vao);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glDrawArrays(GL_TRIANGLES, 0, snapshot.normal_vertices_count); glDrawArrays(GL_TRIANGLES, 0, snapshot.normal_vertices_count);
glBindBuffer(GL_ARRAY_BUFFER, 0);
rendered_sum++; rendered_sum++;
} }
@@ -478,40 +479,19 @@ void Renderer::render_world() {
if (dist2d <= CROSS_PLANE_DISTANCE * 16) { if (dist2d <= CROSS_PLANE_DISTANCE * 16) {
glBindTexture(GL_TEXTURE_2D_ARRAY, glBindTexture(GL_TEXTURE_2D_ARRAY,
m_texture_manager.get_cross_plane_array()); m_texture_manager.get_cross_plane_array());
glBindBuffer(GL_ARRAY_BUFFER, snapshot.cross_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); glBindVertexArray(snapshot.cross_vao);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glDrawArrays(GL_TRIANGLES, 0, snapshot.cross_vertices_count); glDrawArrays(GL_TRIANGLES, 0, snapshot.cross_vertices_count);
glBindBuffer(GL_ARRAY_BUFFER, 0);
} }
} }
if (snapshot.normal_discard_vertices_count != 0) { if (snapshot.normal_discard_vertices_count != 0) {
glBindTexture(GL_TEXTURE_2D_ARRAY, glBindTexture(GL_TEXTURE_2D_ARRAY,
m_texture_manager.get_texture_array()); m_texture_manager.get_texture_array());
glBindBuffer(GL_ARRAY_BUFFER, snapshot.normal_discard_vbo); glBindVertexArray(snapshot.normal_discard_vao);
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, glDrawArrays(GL_TRIANGLES, 0,
snapshot.normal_discard_vertices_count); snapshot.normal_discard_vertices_count);
glBindBuffer(GL_ARRAY_BUFFER, 0);
} }
} }
@@ -526,11 +506,15 @@ void Renderer::render_world() {
// pass one accumulate // pass one accumulate
auto& accum_shader = get_shader("accum"); auto& accum_shader = get_shader("accum");
accum_shader.use(); accum_shader.use();
GLint mv_loc = accum_shader.loc("mv_matrix"); GLint mv_loc = accum_shader.loc("mv_matrix");
GLint proj_loc = accum_shader.loc("proj_matrix"); GLint proj_loc = accum_shader.loc("proj_matrix");
glUniformMatrix4fv(mv_loc, 1, GL_FALSE, glm::value_ptr(m_mv_mat)); glUniformMatrix4fv(mv_loc, 1, GL_FALSE, glm::value_ptr(m_mv_mat));
glUniformMatrix4fv(proj_loc, 1, GL_FALSE, glm::value_ptr(m_p_mat)); glUniformMatrix4fv(proj_loc, 1, GL_FALSE, glm::value_ptr(m_p_mat));
glBindFramebuffer(GL_FRAMEBUFFER, m_oit_fbo); glBindFramebuffer(GL_FRAMEBUFFER, m_oit_fbo);
glClearBufferfv(GL_COLOR, 0, glm::value_ptr(glm::vec4(0.0f))); glClearBufferfv(GL_COLOR, 0, glm::value_ptr(glm::vec4(0.0f)));
float one = 1.0f; float one = 1.0f;
glClearBufferfv(GL_COLOR, 1, &one); glClearBufferfv(GL_COLOR, 1, &one);
@@ -551,20 +535,9 @@ void Renderer::render_world() {
if (snapshot.normal_blend_vertices_count != 0) { if (snapshot.normal_blend_vertices_count != 0) {
glBindTexture(GL_TEXTURE_2D_ARRAY, glBindTexture(GL_TEXTURE_2D_ARRAY,
m_texture_manager.get_texture_array()); m_texture_manager.get_texture_array());
glBindBuffer(GL_ARRAY_BUFFER, snapshot.normal_blend_vbo); glBindVertexArray(snapshot.normal_blend_vao);
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, snapshot.normal_blend_vertices_count); glDrawArrays(GL_TRIANGLES, 0, snapshot.normal_blend_vertices_count);
glBindBuffer(GL_ARRAY_BUFFER, 0);
} }
} }
auto& composite_shader = get_shader("composite"); auto& composite_shader = get_shader("composite");
@@ -577,16 +550,7 @@ void Renderer::render_world() {
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glBindVertexArray(m_vao[6]); glBindVertexArray(m_vao[0]);
glBindBuffer(GL_ARRAY_BUFFER, m_quad_vbo);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float),
(void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float),
(void*)(2 * sizeof(float)));
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_accum_texture); glBindTexture(GL_TEXTURE_2D, m_accum_texture);