From 52d581cd3c648fba623a55034e0797e66ea52ce1 Mon Sep 17 00:00:00 2001 From: korenkonder Date: Tue, 25 Apr 2023 17:57:14 +0300 Subject: [PATCH] Object buffer optimization --- src/CRE/object.cpp | 473 ++++++++++++++++++++++++------------- src/CRE/object.hpp | 18 ++ src/CRE/render_context.cpp | 52 +++- src/CRE/render_context.hpp | 16 +- src/CRE/rob/ex_block.cpp | 16 +- 5 files changed, 398 insertions(+), 177 deletions(-) diff --git a/src/CRE/object.cpp b/src/CRE/object.cpp index 5b60ec00..5d3d0697 100644 --- a/src/CRE/object.cpp +++ b/src/CRE/object.cpp @@ -39,7 +39,7 @@ obj_mesh_index_buffer::obj_mesh_index_buffer() : buffer(), size() { } bool obj_mesh_index_buffer::load(obj_mesh& mesh) { - int32_t num_index = 0; + size_t num_index = 0; for (uint32_t i = 0; i < mesh.num_submesh; i++) num_index += mesh.submesh_array[i].num_index; @@ -49,46 +49,9 @@ bool obj_mesh_index_buffer::load(obj_mesh& mesh) { } uint16_t* indices = force_malloc_s(uint16_t, num_index); - uint16_t* _indices = indices; - for (uint32_t k = 0; k < mesh.num_submesh; k++) { - obj_sub_mesh& sub_mesh = mesh.submesh_array[k]; - uint32_t num_index = sub_mesh.num_index; - uint32_t* index = sub_mesh.index_array; - for (uint32_t l = 0; l < num_index; l++, index++) - *_indices++ = (uint16_t)*index; - } + obj_mesh_index_buffer::fill_data(indices, mesh); - _indices = indices; - for (uint32_t i = 0, offset = 0; i < mesh.num_submesh; i++) { - obj_sub_mesh& sub_mesh = mesh.submesh_array[i]; - - sub_mesh.first_index = 0; - sub_mesh.last_index = 0; - sub_mesh.index_offset = 0; - if (sub_mesh.index_format != OBJ_INDEX_U16) - continue; - - uint16_t first_index = 0xFFFF; - uint16_t last_index = 0; - uint32_t num_index = sub_mesh.num_index; - for (uint32_t j = 0; j < num_index; j++) { - uint16_t index = *_indices++; - if (index == 0xFFFF) - continue; - - if (first_index > index) - first_index = index; - if (last_index < index) - last_index = index; - } - - sub_mesh.first_index = first_index; - sub_mesh.last_index = last_index; - sub_mesh.index_offset = (int32_t)(sizeof(uint16_t) * offset); - offset += sub_mesh.num_index; - } - - bool ret = load_data((size_t)num_index * sizeof(uint16_t), indices); + bool ret = load_data(num_index * sizeof(uint16_t), indices); free_def(indices); return ret; } @@ -116,7 +79,52 @@ void obj_mesh_index_buffer::unload() { size = 0; } +void* obj_mesh_index_buffer::fill_data(void* data, obj_mesh& mesh) { + uint16_t* indices = (uint16_t*)data; + for (uint32_t i = 0; i < mesh.num_submesh; i++) { + obj_sub_mesh& sub_mesh = mesh.submesh_array[i]; + uint32_t num_index = sub_mesh.num_index; + uint32_t* index = sub_mesh.index_array; + for (uint32_t j = num_index; j; j--, index++) + *indices++ = (uint16_t)*index; + } + + indices = (uint16_t*)data; + for (uint32_t i = 0, offset = 0; i < mesh.num_submesh; i++) { + obj_sub_mesh& sub_mesh = mesh.submesh_array[i]; + + sub_mesh.first_index = 0; + sub_mesh.last_index = 0; + sub_mesh.index_offset = 0; + if (sub_mesh.index_format != OBJ_INDEX_U16) + continue; + + uint16_t first_index = 0xFFFF; + uint16_t last_index = 0; + for (uint32_t j = sub_mesh.num_index; j; j--) { + uint16_t index = *indices++; + if (index == 0xFFFF) + continue; + + if (first_index > index) + first_index = index; + if (last_index < index) + last_index = index; + } + + sub_mesh.first_index = first_index; + sub_mesh.last_index = last_index; + sub_mesh.index_offset = (int32_t)(offset * sizeof(uint16_t)); + offset += sub_mesh.num_index; + } + return (void*)indices; +} + +#if SHARED_OBJECT_BUFFER +obj_mesh_vertex_buffer::obj_mesh_vertex_buffer() : count(), buffers(), size(), offset(), index() { +#else obj_mesh_vertex_buffer::obj_mesh_vertex_buffer() : count(), buffers(), size(), index() { +#endif } @@ -131,6 +139,14 @@ GLuint obj_mesh_vertex_buffer::get_buffer() { return 0; } +#if SHARED_OBJECT_BUFFER +size_t obj_mesh_vertex_buffer::get_offset() { + if (buffers[0]) + return offset; + return 0; +} +#endif + GLsizeiptr obj_mesh_vertex_buffer::get_size() { if (buffers[0]) return size; @@ -148,133 +164,7 @@ bool obj_mesh_vertex_buffer::load(obj_mesh& mesh, bool dynamic) { size_vertex = obj_vertex_format_get_vertex_size_comp(mesh.vertex_format); void* vertex = force_malloc(size_vertex * mesh.num_vertex); - if (vertex) { - obj_vertex_format vertex_format = mesh.vertex_format; - obj_vertex_data* vtx = mesh.vertex_array; - int32_t num_vertex = mesh.num_vertex; - size_t d = (size_t)vertex; - if (!mesh.attrib.m.compressed) { - for (int32_t i = 0; i < num_vertex; i++, vtx++) { - if (vertex_format & OBJ_VERTEX_POSITION) { - *(vec3*)d = vtx->position; - d += 12; - } - - if (vertex_format & OBJ_VERTEX_NORMAL) { - *(vec3*)d = vtx->normal; - d += 12; - } - - if (vertex_format & OBJ_VERTEX_TANGENT) { - *(vec4*)d = vtx->tangent; - d += 16; - } - - if (vertex_format & OBJ_VERTEX_BINORMAL) { - *(vec3*)d = vtx->binormal; - d += 12; - } - - if (vertex_format & OBJ_VERTEX_TEXCOORD0) { - *(vec2*)d = vtx->texcoord0; - d += 8; - } - - if (vertex_format & OBJ_VERTEX_TEXCOORD1) { - *(vec2*)d = vtx->texcoord1; - d += 8; - } - - if (vertex_format & OBJ_VERTEX_TEXCOORD2) { - *(vec2*)d = vtx->texcoord2; - d += 8; - } - - if (vertex_format & OBJ_VERTEX_TEXCOORD3) { - *(vec2*)d = vtx->texcoord3; - d += 8; - } - - if (vertex_format & OBJ_VERTEX_COLOR0) { - *(vec4*)d = vtx->color0; - d += 16; - } - - if (vertex_format & OBJ_VERTEX_COLOR1) { - *(vec4*)d = vtx->color1; - d += 16; - } - - if (vertex_format & OBJ_VERTEX_BONE_DATA) { - *(vec4*)d = vtx->bone_weight; - d += 16; - *(vec4i16*)d = vtx->bone_index; - d += 8; - } - - if (vertex_format & OBJ_VERTEX_UNKNOWN) { - *(vec4*)d = vtx->unknown; - d += 16; - } - } - } - else { - for (int32_t i = 0; i < num_vertex; i++, vtx++) { - if (vertex_format & OBJ_VERTEX_POSITION) { - *(vec3*)d = vtx->position; - d += 12; - } - - if (vertex_format & OBJ_VERTEX_NORMAL) { - vec3 normal = vtx->normal * 32727.0f; - vec3_to_vec3i16(normal, *(vec3i16*)d); - *(int16_t*)(d + 6) = 0; - d += 8; - } - - if (vertex_format & OBJ_VERTEX_TANGENT) { - vec4 tangent = vtx->tangent * 32727.0f; - vec4_to_vec4i16(tangent, *(vec4i16*)d); - d += 8; - } - - if (vertex_format & OBJ_VERTEX_TEXCOORD0) { - vec2_to_vec2h(vtx->texcoord0, *(vec2h*)d); - d += 4; - } - - if (vertex_format & OBJ_VERTEX_TEXCOORD1) { - vec2_to_vec2h(vtx->texcoord1, *(vec2h*)d); - d += 4; - } - - if (vertex_format & OBJ_VERTEX_TEXCOORD2) { - vec2_to_vec2h(vtx->texcoord2, *(vec2h*)d); - d += 4; - } - - if (vertex_format & OBJ_VERTEX_TEXCOORD3) { - vec2_to_vec2h(vtx->texcoord3, *(vec2h*)d); - d += 4; - } - - if (vertex_format & OBJ_VERTEX_COLOR0) { - vec4 color0 = vtx->color0; - vec4_to_vec4h(color0, *(vec4h*)d); - d += 8; - } - - if (vertex_format & OBJ_VERTEX_BONE_DATA) { - vec4 bone_weight = vtx->bone_weight * 65535.0f; - vec4_to_vec4u16(bone_weight, *(vec4u16*)d); - d += 8; - - *(vec4i16*)d = vtx->bone_index; - d += 8; - } - } - } - } + obj_mesh_vertex_buffer::fill_data(vertex, mesh); mesh.size_vertex = (int32_t)size_vertex; bool ret = load_data(size_vertex * mesh.num_vertex, vertex, mesh.attrib.m.double_buffer ? 2 : 1, dynamic); @@ -288,6 +178,9 @@ bool obj_mesh_vertex_buffer::load_data(size_t size, const void* data, int32_t co this->count = count; this->size = (GLsizeiptr)size; +#if SHARED_OBJECT_BUFFER + offset = 0; +#endif glGenBuffers(count, buffers); for (int32_t i = 0; i < count; i++) { @@ -309,11 +202,148 @@ void obj_mesh_vertex_buffer::unload() { count = 0; buffers[0] = 0; +#if SHARED_OBJECT_BUFFER + offset = 0; +#endif size = 0; index = 0; } +void* obj_mesh_vertex_buffer::fill_data(void* data, obj_mesh& mesh) { + obj_vertex_format vertex_format = mesh.vertex_format; + obj_vertex_data* vtx = mesh.vertex_array; + uint32_t num_vertex = mesh.num_vertex; + size_t d = (size_t)data; + if (!mesh.attrib.m.compressed) { + size_t size = (size_t)num_vertex * mesh.size_vertex; + for (uint32_t i = num_vertex; i; i--, vtx++) { + if (vertex_format & OBJ_VERTEX_POSITION) { + *(vec3*)d = vtx->position; + d += 12; + } + + if (vertex_format & OBJ_VERTEX_NORMAL) { + *(vec3*)d = vtx->normal; + d += 12; + } + + if (vertex_format & OBJ_VERTEX_TANGENT) { + *(vec4*)d = vtx->tangent; + d += 16; + } + + if (vertex_format & OBJ_VERTEX_BINORMAL) { + *(vec3*)d = vtx->binormal; + d += 12; + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD0) { + *(vec2*)d = vtx->texcoord0; + d += 8; + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD1) { + *(vec2*)d = vtx->texcoord1; + d += 8; + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD2) { + *(vec2*)d = vtx->texcoord2; + d += 8; + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD3) { + *(vec2*)d = vtx->texcoord3; + d += 8; + } + + if (vertex_format & OBJ_VERTEX_COLOR0) { + *(vec4*)d = vtx->color0; + d += 16; + } + + if (vertex_format & OBJ_VERTEX_COLOR1) { + *(vec4*)d = vtx->color1; + d += 16; + } + + if (vertex_format & OBJ_VERTEX_BONE_DATA) { + *(vec4*)d = vtx->bone_weight; + d += 16; + *(vec4i16*)d = vtx->bone_index; + d += 8; + } + + if (vertex_format & OBJ_VERTEX_UNKNOWN) { + *(vec4*)d = vtx->unknown; + d += 16; + } + } + } + else { + for (uint32_t i = num_vertex; i; i--, vtx++) { + if (vertex_format & OBJ_VERTEX_POSITION) { + *(vec3*)d = vtx->position; + d += 12; + } + + if (vertex_format & OBJ_VERTEX_NORMAL) { + vec3 normal = vtx->normal * 32727.0f; + vec3_to_vec3i16(normal, *(vec3i16*)d); + *(int16_t*)(d + 6) = 0; + d += 8; + } + + if (vertex_format & OBJ_VERTEX_TANGENT) { + vec4 tangent = vtx->tangent * 32727.0f; + vec4_to_vec4i16(tangent, *(vec4i16*)d); + d += 8; + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD0) { + vec2_to_vec2h(vtx->texcoord0, *(vec2h*)d); + d += 4; + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD1) { + vec2_to_vec2h(vtx->texcoord1, *(vec2h*)d); + d += 4; + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD2) { + vec2_to_vec2h(vtx->texcoord2, *(vec2h*)d); + d += 4; + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD3) { + vec2_to_vec2h(vtx->texcoord3, *(vec2h*)d); + d += 4; + } + + if (vertex_format & OBJ_VERTEX_COLOR0) { + vec4 color0 = vtx->color0; + vec4_to_vec4h(color0, *(vec4h*)d); + d += 8; + } + + if (vertex_format & OBJ_VERTEX_BONE_DATA) { + vec4 bone_weight = vtx->bone_weight * 65535.0f; + vec4_to_vec4u16(bone_weight, *(vec4u16*)d); + d += 8; + + *(vec4i16*)d = vtx->bone_index; + d += 8; + } + } + } + return (void*)d; +} + +#if SHARED_OBJECT_BUFFER +obj_index_buffer::obj_index_buffer() : mesh_num(), mesh_data(), buffer() { +#else obj_index_buffer::obj_index_buffer() : mesh_num(), mesh_data() { +#endif } @@ -323,23 +353,73 @@ bool obj_index_buffer::load(obj& obj) { if (!mesh_data) return false; +#if SHARED_OBJECT_BUFFER + size_t buffer_size = 0; + for (uint32_t i = 0; i < mesh_num; i++) { + obj_mesh& mesh = obj.mesh_array[i]; + size_t num_index = 0; + for (uint32_t i = 0; i < mesh.num_submesh; i++) + num_index += mesh.submesh_array[i].num_index; + buffer_size += num_index * sizeof(uint16_t); + } + + void* index = force_malloc(buffer_size); + if (index) { + void* data = index; + for (uint32_t i = 0; i < mesh_num; i++) { + mesh_data[i].size = (GLsizeiptr)buffer_size; + + uint32_t offset = (uint32_t)((size_t)data - (size_t)index); + data = obj_mesh_index_buffer::fill_data(data, obj.mesh_array[i]); + + obj_mesh& mesh = obj.mesh_array[i]; + for (uint32_t j = 0; j < mesh.num_submesh; j++) + mesh.submesh_array[j].index_offset += offset; + } + } + + glGenBuffers(1, &buffer); + gl_state_bind_element_array_buffer(buffer, true); + if (GLAD_GL_VERSION_4_4) + glBufferStorage(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)buffer_size, index, 0); + else + glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)buffer_size, index, GL_STATIC_DRAW); + gl_state_bind_element_array_buffer(0); + free_def(index); + + for (uint32_t i = 0; i < mesh_num; i++) + mesh_data[i].buffer = buffer; +#else for (uint32_t i = 0; i < mesh_num; i++) if (!mesh_data[i].load(obj.mesh_array[i])) return false; +#endif return true; } void obj_index_buffer::unload() { if (mesh_data) { +#if SHARED_OBJECT_BUFFER + if (buffer) + glDeleteBuffers(1, &buffer); +#else for (uint32_t i = 0; i < mesh_num; i++) mesh_data[i].unload(); +#endif delete[] mesh_data; } mesh_data = 0; mesh_num = 0; +#if SHARED_OBJECT_BUFFER + buffer = 0; +#endif } +#if SHARED_OBJECT_BUFFER +obj_vertex_buffer::obj_vertex_buffer() : mesh_num(), mesh_data(), buffers() { +#else obj_vertex_buffer::obj_vertex_buffer() : mesh_num(), mesh_data() { +#endif } @@ -349,20 +429,79 @@ bool obj_vertex_buffer::load(obj& obj) { if (!mesh_data) return false; +#if SHARED_OBJECT_BUFFER + size_t buffer_size = 0; + bool double_buffer = false; + for (uint32_t i = 0; i < mesh_num; i++) { + obj_mesh& mesh = obj.mesh_array[i]; + if (!mesh.num_vertex || !mesh.vertex_array) + continue; + + size_t size_vertex; + if (!mesh.attrib.m.compressed) + size_vertex = obj_vertex_format_get_vertex_size(mesh.vertex_format); + else + size_vertex = obj_vertex_format_get_vertex_size_comp(mesh.vertex_format); + mesh.size_vertex = (int32_t)size_vertex; + + buffer_size += size_vertex * mesh.num_vertex; + double_buffer |= !!mesh.attrib.m.double_buffer; + } + + uint32_t count = double_buffer ? 2 : 1; + + void* vertex = force_malloc(buffer_size); + if (vertex) { + void* data = vertex; + for (uint32_t i = 0; i < mesh_num; i++) { + obj_mesh_vertex_buffer& mesh_buffer = mesh_data[i]; + mesh_buffer.offset = (size_t)data - (size_t)vertex; + mesh_buffer.count = count; + mesh_buffer.size = (GLsizeiptr)buffer_size; + + data = obj_mesh_vertex_buffer::fill_data(data, obj.mesh_array[i]); + } + } + + glGenBuffers(count, buffers); + for (uint32_t i = 0; i < count; i++) { + gl_state_bind_array_buffer(buffers[i], true); + if (GLAD_GL_VERSION_4_4) + glBufferStorage(GL_ARRAY_BUFFER, + (GLsizeiptr)buffer_size, vertex, 0); + else + glBufferData(GL_ARRAY_BUFFER, + (GLsizeiptr)buffer_size, vertex, GL_STATIC_DRAW); + } + gl_state_bind_array_buffer(0); + free_def(vertex); + + for (uint32_t i = 0; i < mesh_num; i++) + memcpy(mesh_data[i].buffers, buffers, count * sizeof(GLuint)); +#else for (uint32_t i = 0; i < mesh_num; i++) if (!mesh_data[i].load(obj.mesh_array[i])) return false; +#endif return true; } void obj_vertex_buffer::unload() { if (mesh_data) { +#if SHARED_OBJECT_BUFFER + if (buffers[0]) + glDeleteBuffers(mesh_data[0].count, buffers); +#else for (uint32_t i = 0; i < mesh_num; i++) mesh_data[i].unload(); +#endif delete[] mesh_data; } mesh_data = 0; mesh_num = 0; +#if SHARED_OBJECT_BUFFER + buffers[0] = 0; +#endif } obj_set_handler::obj_set_handler() : obj_loaded(), tex_loaded(), obj_set(), diff --git a/src/CRE/object.hpp b/src/CRE/object.hpp index f37d898a..07f5c6dd 100644 --- a/src/CRE/object.hpp +++ b/src/CRE/object.hpp @@ -17,6 +17,8 @@ #include "static_var.hpp" #include "texture.hpp" +#define SHARED_OBJECT_BUFFER (1) + struct obj_mesh_index_buffer { GLuint buffer; GLsizeiptr size; @@ -26,27 +28,40 @@ struct obj_mesh_index_buffer { bool load(obj_mesh& mesh); bool load_data(size_t size, const void* data); void unload(); + + static void* store_data(void* data, obj_mesh& mesh); }; struct obj_mesh_vertex_buffer { uint32_t count; GLuint buffers[3]; GLsizeiptr size; +#if SHARED_OBJECT_BUFFER + size_t offset; +#endif uint32_t index; obj_mesh_vertex_buffer(); void cycle_index(); GLuint get_buffer(); +#if SHARED_OBJECT_BUFFER + size_t get_offset(); +#endif GLsizeiptr get_size(); bool load(obj_mesh& mesh, bool dynamic = false); bool load_data(size_t size, const void* data, int32_t count, bool dynamic); void unload(); + + static void* store_data(void* data, obj_mesh& mesh); }; struct obj_index_buffer { uint32_t mesh_num; obj_mesh_index_buffer* mesh_data; +#if SHARED_OBJECT_BUFFER + GLuint buffer; +#endif obj_index_buffer(); @@ -57,6 +72,9 @@ struct obj_index_buffer { struct obj_vertex_buffer { uint32_t mesh_num; obj_mesh_vertex_buffer* mesh_data; +#if SHARED_OBJECT_BUFFER + GLuint buffers[3]; +#endif obj_vertex_buffer(); diff --git a/src/CRE/render_context.cpp b/src/CRE/render_context.cpp index c68026b1..c43e76d0 100644 --- a/src/CRE/render_context.cpp +++ b/src/CRE/render_context.cpp @@ -218,7 +218,10 @@ namespace mdl { void ObjData::init_sub_mesh(DispManager* disp_manager, const mat4* mat, float_t radius, obj_sub_mesh* sub_mesh, obj_mesh* mesh, obj_material_data* material, std::vector* textures, int32_t mat_count, mat4* mats, GLuint vertex_buffer, - GLuint index_buffer, vec4* blend_color, vec4* emission, int32_t morph_vertex_buffer, + GLuint index_buffer, vec4* blend_color, vec4* emission, GLuint morph_vertex_buffer, +#if SHARED_OBJECT_BUFFER + size_t vertex_buffer_offset, size_t morph_vertex_buffer_offset, +#endif int32_t instances_count, mat4* instances_mat, void(*func)(const ObjSubMeshArgs*)) { kind = mdl::OBJ_KIND_NORMAL; this->mat = *mat; @@ -235,6 +238,10 @@ namespace mdl { args->vertex_buffer = vertex_buffer; args->index_buffer = index_buffer; args->morph_vertex_buffer = morph_vertex_buffer; +#if SHARED_OBJECT_BUFFER + args->vertex_buffer_offset = vertex_buffer_offset; + args->morph_vertex_buffer_offset = morph_vertex_buffer_offset; +#endif args->texture_pattern_count = disp_manager->texture_pattern_count; for (int32_t i = 0; i < disp_manager->texture_pattern_count && i < TEXTURE_PATTERN_COUNT; i++) @@ -418,6 +425,10 @@ namespace mdl { GLuint vertex_buffer = args->vertex_buffer; GLuint morph_vertex_buffer = args->morph_vertex_buffer; +#if SHARED_OBJECT_BUFFER + size_t vertex_buffer_offset = args->vertex_buffer_offset; + size_t morph_vertex_buffer_offset = args->morph_vertex_buffer_offset; +#endif GLuint index_buffer = args->index_buffer; int32_t texcoord_array[2] = { -1, -1 }; @@ -449,6 +460,10 @@ namespace mdl { for (DispManager::vertex_array& i : vertex_array_cache) if (i.alive_time >= 0 && i.vertex_buffer == vertex_buffer && i.morph_vertex_buffer == morph_vertex_buffer +#if SHARED_OBJECT_BUFFER + && i.vertex_buffer_offset == vertex_buffer_offset + && i.morph_vertex_buffer_offset == morph_vertex_buffer_offset +#endif && i.index_buffer == index_buffer && i.vertex_format == vertex_format && i.size_vertex == size_vertex && i.compressed == compressed && !memcmp(i.vertex_attrib_buffer_binding, @@ -499,6 +514,10 @@ namespace mdl { vertex_array->vertex_buffer = vertex_buffer; vertex_array->morph_vertex_buffer = morph_vertex_buffer; +#if SHARED_OBJECT_BUFFER + vertex_array->vertex_buffer_offset = vertex_buffer_offset; + vertex_array->morph_vertex_buffer_offset = morph_vertex_buffer_offset; +#endif vertex_array->index_buffer = index_buffer; vertex_array->alive_time = 60; vertex_array->vertex_format = vertex_format; @@ -513,7 +532,11 @@ namespace mdl { if (index_buffer) gl_state_bind_element_array_buffer(index_buffer, true); +#if SHARED_OBJECT_BUFFER + size_t offset = vertex_buffer_offset; +#else size_t offset = 0; +#endif if (vertex_format & OBJ_VERTEX_POSITION) { if (!vertex_array->vertex_attrib_array[POSITION_INDEX]) { glEnableVertexAttribArray(POSITION_INDEX); @@ -703,7 +726,11 @@ namespace mdl { if (morph_vertex_buffer) { gl_state_bind_array_buffer(morph_vertex_buffer); +#if SHARED_OBJECT_BUFFER + offset = morph_vertex_buffer_offset; +#else offset = 0; +#endif if (vertex_format & OBJ_VERTEX_POSITION) { if (!vertex_array->vertex_attrib_array[MORPH_POSITION_INDEX]) { glEnableVertexAttribArray(MORPH_POSITION_INDEX); @@ -1426,6 +1453,16 @@ namespace mdl { if (obj_vertex_buf) vertex_buffer = obj_vertex_buf[i].get_buffer(); +#if SHARED_OBJECT_BUFFER + size_t morph_vertex_buffer_offset = 0; + if (obj_morph_vertex_buf) + morph_vertex_buffer_offset = obj_morph_vertex_buf[i].get_offset(); + + size_t vertex_buffer_offset = 0; + if (obj_vertex_buf) + vertex_buffer_offset = obj_vertex_buf[i].get_offset(); +#endif + if (!vertex_buffer || !index_buffer || obj_morph_vertex_buf && !morph_vertex_buffer) { printf_debug("mdl::DispManager::entry_obj: no vertex or index mesh buffer to draw;\n"); printf_debug(" Object: %s; Mesh: %s; Sub Mesh: %d\n", object->name, mesh->name, j); @@ -1505,7 +1542,12 @@ namespace mdl { data->init_sub_mesh(this, mat, object->bounding_sphere.radius, sub_mesh, mesh, material, textures, num_bone_index, mats, vertex_buffer, index_buffer, +#if SHARED_OBJECT_BUFFER + &_blend_color, &_emission, morph_vertex_buffer, + vertex_buffer_offset, morph_vertex_buffer_offset, instances_count, instances_mat, func); +#else &_blend_color, &_emission, morph_vertex_buffer, instances_count, instances_mat, func); +#endif if (obj_flags & mdl::OBJ_SHADOW_OBJECT) { entry_list((ObjType)(OBJ_TYPE_SHADOW_OBJECT_CHARA @@ -1816,6 +1858,10 @@ namespace mdl { GLuint vertex_buffer = args->vertex_buffer; GLuint morph_vertex_buffer = args->morph_vertex_buffer; +#if SHARED_OBJECT_BUFFER + size_t vertex_buffer_offset = args->vertex_buffer_offset; + size_t morph_vertex_buffer_offset = args->morph_vertex_buffer_offset; +#endif GLuint index_buffer = args->index_buffer; int32_t texcoord_array[2] = { -1, -1 }; @@ -1847,6 +1893,10 @@ namespace mdl { for (DispManager::vertex_array& i : vertex_array_cache) if (i.alive_time > 0 && i.vertex_buffer == vertex_buffer && i.morph_vertex_buffer == morph_vertex_buffer +#if SHARED_OBJECT_BUFFER + && i.vertex_buffer_offset == vertex_buffer_offset + && i.morph_vertex_buffer_offset == morph_vertex_buffer_offset +#endif && i.index_buffer == index_buffer && i.vertex_format == vertex_format && i.size_vertex == size_vertex && i.compressed == compressed && !memcmp(i.vertex_attrib_buffer_binding, diff --git a/src/CRE/render_context.hpp b/src/CRE/render_context.hpp index c967b549..a763eb91 100644 --- a/src/CRE/render_context.hpp +++ b/src/CRE/render_context.hpp @@ -276,6 +276,10 @@ namespace mdl { bool self_shadow; shadow_type_enum shadow; GLuint morph_vertex_buffer; +#if SHARED_OBJECT_BUFFER + size_t vertex_buffer_offset; + size_t morph_vertex_buffer_offset; +#endif float_t morph_weight; int32_t texture_pattern_count; texture_pattern_struct texture_pattern_array[TEXTURE_PATTERN_COUNT]; @@ -391,7 +395,10 @@ namespace mdl { void init_sub_mesh(DispManager* disp_manager, const mat4* mat, float_t radius, obj_sub_mesh* sub_mesh, obj_mesh* mesh, obj_material_data* material, std::vector* textures, int32_t mat_count, mat4* mats, GLuint vertex_buffer, - GLuint index_buffer, vec4* blend_color, vec4* emission, int32_t morph_vertex_buffer, + GLuint index_buffer, vec4* blend_color, vec4* emission, GLuint morph_vertex_buffer, +#if SHARED_OBJECT_BUFFER + size_t vertex_buffer_offset, size_t morph_vertex_buffer_offset, +#endif int32_t instances_count, mat4* instances_mat, void(*func)(const ObjSubMeshArgs*)); void init_translucent(const mat4* mat, ObjTranslucentArgs* translucent); void init_user(const mat4* mat, UserArgsFunc func, void* data); @@ -448,8 +455,15 @@ namespace mdl { struct DispManager { struct vertex_array { +#if SHARED_OBJECT_BUFFER + GLuint vertex_buffer; + size_t vertex_buffer_offset; + GLuint morph_vertex_buffer; + size_t morph_vertex_buffer_offset; +#else GLuint vertex_buffer; GLuint morph_vertex_buffer; +#endif GLuint index_buffer; int32_t alive_time; GLuint vertex_array; diff --git a/src/CRE/rob/ex_block.cpp b/src/CRE/rob/ex_block.cpp index 72b894ef..86672eeb 100644 --- a/src/CRE/rob/ex_block.cpp +++ b/src/CRE/rob/ex_block.cpp @@ -894,8 +894,8 @@ void RobCloth::ResetData() { mesh[1] = {}; vertex_buffer[0].unload(); vertex_buffer[1].unload(); - index_buffer[0].buffer = 0; - index_buffer[1].buffer = 0; + index_buffer[0] = {}; + index_buffer[1] = {}; motion_reset_data.clear(); reset_data_list = 0; } @@ -996,13 +996,13 @@ void RobCloth::InitData(size_t root_count, size_t nodes_count, obj_skin_block_cl for (int32_t i = 0; i < 2; i++) { RobClothSubMeshArray& submesh = this->submesh[i]; for (uint32_t j = 0; j < mesh[i].num_submesh; j++) { - obj_sub_mesh& v27 = submesh.arr[j]; - v27 = mesh[i].submesh_array[j]; + obj_sub_mesh& cloth_mesh = submesh.arr[j]; + cloth_mesh = mesh[i].submesh_array[j]; + cloth_mesh.attrib.m.cloth = 0; + cloth_mesh.bounding_sphere.radius = 1000.0f; + cloth_mesh.axis_aligned_bounding_box.center = 0.0f; + cloth_mesh.axis_aligned_bounding_box.size = { 1000.0f, 1000.0f, 1000.0f }; mesh[i].submesh_array[j].attrib.m.cloth = 1; - v27.attrib.m.cloth = 0; - v27.bounding_sphere.radius = 1000.0f; - v27.axis_aligned_bounding_box.center = 0.0f; - v27.axis_aligned_bounding_box.size = { 1000.0f, 1000.0f, 1000.0f }; } mesh[i].submesh_array = submesh.arr; mesh[i].bounding_sphere.radius = 1000.0f;