From f725d2450d8092fabec5df4bdddf090194b29762 Mon Sep 17 00:00:00 2001 From: korenkonder Date: Wed, 20 Dec 2023 14:30:46 +0300 Subject: [PATCH] Better handling of deleted data in vertex array cache --- src/DivaGL/mdl/disp_manager.cpp | 34 +++++++++++++++++++++++++++++---- src/DivaGL/mdl/disp_manager.hpp | 5 ++++- src/DivaGL/object.cpp | 5 +++++ 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/DivaGL/mdl/disp_manager.cpp b/src/DivaGL/mdl/disp_manager.cpp index 169159f..43f1fb1 100644 --- a/src/DivaGL/mdl/disp_manager.cpp +++ b/src/DivaGL/mdl/disp_manager.cpp @@ -251,6 +251,21 @@ namespace mdl { args.user.data = data; } + void DispManager::vertex_array::reset_vertex_attrib() { + alive_time = 0; + vertex_buffer = 0; + morph_vertex_buffer = 0; + + gl_state_bind_vertex_array(vertex_array); + for (int32_t i = 0; i < 16; i++) + if (vertex_attrib_array[i]) { + glDisableVertexAttribArray(i); + vertex_attrib_array[i] = false; + } + gl_state_bind_array_buffer(0, true); + gl_state_bind_element_array_buffer(0, true); + gl_state_bind_vertex_array(0); + } void DispManager::add_vertex_array(ObjSubMeshArgs* args) { const obj_mesh* mesh = args->mesh; @@ -1276,12 +1291,16 @@ namespace mdl { } } + void DispManager::check_index_buffer(GLuint buffer) { + for (DispManager::vertex_array& i : vertex_array_cache) + if (i.alive_time > 0 && i.index_buffer == buffer) + i.reset_vertex_attrib(); + } + void DispManager::check_vertex_arrays() { for (DispManager::vertex_array& i : vertex_array_cache) - if (i.alive_time > 0 && --i.alive_time <= 0) { - i.vertex_buffer = 0; - i.morph_vertex_buffer = 0; - } + if (i.alive_time > 0 && --i.alive_time <= 0) + i.reset_vertex_attrib(); for (DispManager::etc_vertex_array& i : etc_vertex_array_cache) if (i.alive_time > 0 && --i.alive_time <= 0) { @@ -1294,6 +1313,13 @@ namespace mdl { } } + void DispManager::check_vertex_buffer(GLuint buffer) { + for (DispManager::vertex_array& i : vertex_array_cache) + if (i.alive_time > 0 + && (i.vertex_buffer == buffer || i.morph_vertex_buffer == buffer)) + i.reset_vertex_attrib(); + } + void DispManager::draw(ObjType type, int32_t depth_mask, bool a4) { if (get_obj_count(type) < 1) return; diff --git a/src/DivaGL/mdl/disp_manager.hpp b/src/DivaGL/mdl/disp_manager.hpp index 779f50b..bfa5c1a 100644 --- a/src/DivaGL/mdl/disp_manager.hpp +++ b/src/DivaGL/mdl/disp_manager.hpp @@ -338,9 +338,10 @@ namespace mdl { bool vertex_attrib_array[16]; obj_vertex_format vertex_format; GLsizei size_vertex; - bool compressed; GLuint vertex_attrib_buffer_binding[16]; int32_t texcoord_array[2]; + + void reset_vertex_attrib(); }; struct etc_vertex_array { @@ -393,7 +394,9 @@ namespace mdl { mat4* alloc_mat4_array(int32_t count); void buffer_reset(); void calc_obj_radius(mat4* view, mdl::ObjType type); + void check_index_buffer(GLuint buffer); void check_vertex_arrays(); + void check_vertex_buffer(GLuint buffer); void draw(mdl::ObjType type, int32_t depth_mask = 0, bool a4 = true); void draw_translucent(mdl::ObjType type, int32_t alpha); /*void draw_show_vector(mdl::ObjType type, int32_t show_vector);*/ diff --git a/src/DivaGL/object.cpp b/src/DivaGL/object.cpp index 9d5ba77..e331af8 100644 --- a/src/DivaGL/object.cpp +++ b/src/DivaGL/object.cpp @@ -4,6 +4,7 @@ */ #include "object.hpp" +#include "mdl/disp_manager.hpp" #include "gl_state.hpp" #include "wrap.hpp" #include @@ -501,6 +502,8 @@ static void free_index_buffer(GLuint buffer) { if (!buffer) return; + disp_manager->check_index_buffer(buffer); + GLint size; gl_state_bind_element_array_buffer(buffer); glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size); @@ -515,6 +518,8 @@ static void free_vertex_buffer(GLuint buffer) { if (!buffer) return; + disp_manager->check_vertex_buffer(buffer); + GLint size = 0; gl_state_bind_array_buffer(buffer); glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);