From a73661f6b8070de5ea0c07020d2c417dfc78b4f4 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Sun, 13 Apr 2025 22:48:20 +0800 Subject: [PATCH] [Fix] (buffer): fix vao-ibo relationship on renaming --- src/main/cpp/gl/buffer.cpp | 43 ++++++++++++++++++++++++++++++++++---- src/main/cpp/gl/getter.cpp | 1 + 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/main/cpp/gl/buffer.cpp b/src/main/cpp/gl/buffer.cpp index 5079460..643fd16 100644 --- a/src/main/cpp/gl/buffer.cpp +++ b/src/main/cpp/gl/buffer.cpp @@ -20,6 +20,8 @@ unordered_map g_gen_arrays; unordered_map g_bound_buffers; GLuint bound_array = 0; +// fake array - fake ibo +unordered_map g_element_array_buffer_per_vao; unordered_map g_active_mappings; @@ -51,6 +53,18 @@ GLuint find_real_buffer(GLuint key) { return 0; } +GLuint get_ibo_by_vao(GLuint vao) { + return g_element_array_buffer_per_vao[vao]; +} + +GLuint find_bound_array() { + return bound_array; +} + +void update_vao_ibo_binding(GLuint vao, GLuint ibo) { + g_element_array_buffer_per_vao[vao] = ibo; +} + GLuint find_bound_buffer(GLenum key) { GLenum target = 0; switch (key) { @@ -94,6 +108,10 @@ GLuint find_bound_buffer(GLenum key) { target = 0; break; } + if (target == GL_ELEMENT_ARRAY_BUFFER) { + return get_ibo_by_vao(find_bound_array()); + } + auto it = g_bound_buffers.find(target); if (it != g_bound_buffers.end()) return it->second; @@ -119,6 +137,7 @@ void modify_array(GLuint key, GLuint value) { void remove_array(GLuint key) { if (g_gen_arrays.find(key) != g_gen_arrays.end()) g_gen_arrays.erase(key); + g_element_array_buffer_per_vao.erase(key); } GLuint find_real_array(GLuint key) { @@ -129,10 +148,6 @@ GLuint find_real_array(GLuint key) { return 0; } -GLuint find_bound_array() { - return bound_array; -} - static GLenum get_binding_query(GLenum target) { switch(target) { case GL_ARRAY_BUFFER: return GL_ARRAY_BUFFER_BINDING; @@ -174,6 +189,11 @@ void glBindBuffer(GLenum target, GLuint buffer) { LOG() LOG_D("glBindBuffer, target = %s, buffer = %d", glEnumToString(target), buffer) g_bound_buffers[target] = buffer; + // save ibo binding to vao + if (target == GL_ELEMENT_ARRAY_BUFFER) { + update_vao_ibo_binding(find_bound_array(), buffer); + } + if (!has_buffer(buffer) || buffer == 0) { GLES.glBindBuffer(target, buffer); CHECK_GL_ERROR @@ -194,6 +214,11 @@ void glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offs LOG() LOG_D("glBindBufferRange, target = %s, index = %d, buffer = %d, offset = %p, size = %zi", glEnumToString(target), index, buffer, (void*) offset, size) g_bound_buffers[target] = buffer; + // save ibo binding to vao + if (target == GL_ELEMENT_ARRAY_BUFFER) { + update_vao_ibo_binding(find_bound_array(), buffer); + } + if (!has_buffer(buffer) || buffer == 0) { GLES.glBindBufferRange(target, index, buffer, offset, size); CHECK_GL_ERROR @@ -213,6 +238,11 @@ void glBindBufferBase(GLenum target, GLuint index, GLuint buffer) { LOG() LOG_D("glBindBufferBase, target = %s, index = %d, buffer = %d", glEnumToString(target), index, buffer) g_bound_buffers[target] = buffer; + // save ibo binding to vao + if (target == GL_ELEMENT_ARRAY_BUFFER) { + update_vao_ibo_binding(find_bound_array(), buffer); + } + if (!has_buffer(buffer) || buffer == 0) { GLES.glBindBufferBase(target, index, buffer); CHECK_GL_ERROR @@ -434,12 +464,17 @@ void glBindVertexArray(GLuint array) { LOG() LOG_D("glBindVertexArray(%d)", array) bound_array = array; + + // update bound ibo + g_bound_buffers[GL_ELEMENT_ARRAY_BUFFER] = get_ibo_by_vao(array); + if (!has_array(array) || array == 0) { LOG_D("Does not have va=%d found!", array) GLES.glBindVertexArray(array); CHECK_GL_ERROR return; } + GLuint real_array = find_real_array(array); if (!real_array) { LOG_D("va=%d not initialized, initializing...", array) diff --git a/src/main/cpp/gl/getter.cpp b/src/main/cpp/gl/getter.cpp index 9529232..16ff2dd 100644 --- a/src/main/cpp/gl/getter.cpp +++ b/src/main/cpp/gl/getter.cpp @@ -62,6 +62,7 @@ void glGetIntegerv(GLenum pname, GLint *params) { case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: case GL_UNIFORM_BUFFER_BINDING: (*params) = (int) find_bound_buffer(pname); + LOG_D(" -> %d",*params) break; case GL_VERTEX_ARRAY_BINDING: (*params) = (int) find_bound_array();