Path: blob/master/drivers/gles3/storage/mesh_storage.cpp
10000 views
/**************************************************************************/1/* mesh_storage.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#ifdef GLES3_ENABLED3132#include "mesh_storage.h"33#include "config.h"34#include "texture_storage.h"35#include "utilities.h"3637using namespace GLES3;3839MeshStorage *MeshStorage::singleton = nullptr;4041MeshStorage *MeshStorage::get_singleton() {42return singleton;43}4445MeshStorage::MeshStorage() {46singleton = this;4748{49skeleton_shader.shader.initialize();50skeleton_shader.shader_version = skeleton_shader.shader.version_create();51}52}5354MeshStorage::~MeshStorage() {55singleton = nullptr;56skeleton_shader.shader.version_free(skeleton_shader.shader_version);57}5859/* MESH API */6061RID MeshStorage::mesh_allocate() {62return mesh_owner.allocate_rid();63}6465void MeshStorage::mesh_initialize(RID p_rid) {66mesh_owner.initialize_rid(p_rid, Mesh());67}6869void MeshStorage::mesh_free(RID p_rid) {70mesh_clear(p_rid);71mesh_set_shadow_mesh(p_rid, RID());72Mesh *mesh = mesh_owner.get_or_null(p_rid);73ERR_FAIL_NULL(mesh);7475mesh->dependency.deleted_notify(p_rid);76if (mesh->instances.size()) {77ERR_PRINT("deleting mesh with active instances");78}79if (mesh->shadow_owners.size()) {80for (Mesh *E : mesh->shadow_owners) {81Mesh *shadow_owner = E;82shadow_owner->shadow_mesh = RID();83shadow_owner->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);84}85}86mesh_owner.free(p_rid);87}8889void MeshStorage::mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) {90ERR_FAIL_COND(p_blend_shape_count < 0);9192Mesh *mesh = mesh_owner.get_or_null(p_mesh);93ERR_FAIL_NULL(mesh);9495ERR_FAIL_COND(mesh->surface_count > 0); //surfaces already exist96mesh->blend_shape_count = p_blend_shape_count;97}9899bool MeshStorage::mesh_needs_instance(RID p_mesh, bool p_has_skeleton) {100Mesh *mesh = mesh_owner.get_or_null(p_mesh);101ERR_FAIL_NULL_V(mesh, false);102103return mesh->blend_shape_count > 0 || (mesh->has_bone_weights && p_has_skeleton);104}105106void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) {107Mesh *mesh = mesh_owner.get_or_null(p_mesh);108ERR_FAIL_NULL(mesh);109110ERR_FAIL_COND(mesh->surface_count == RS::MAX_MESH_SURFACES);111112#ifdef DEBUG_ENABLED113//do a validation, to catch errors first114{115uint32_t stride = 0;116uint32_t attrib_stride = 0;117uint32_t skin_stride = 0;118119for (int i = 0; i < RS::ARRAY_WEIGHTS; i++) {120if ((p_surface.format & (1ULL << i))) {121switch (i) {122case RS::ARRAY_VERTEX: {123if ((p_surface.format & RS::ARRAY_FLAG_USE_2D_VERTICES) || (p_surface.format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES)) {124stride += sizeof(float) * 2;125} else {126stride += sizeof(float) * 3;127}128} break;129case RS::ARRAY_NORMAL: {130stride += sizeof(uint16_t) * 2;131132} break;133case RS::ARRAY_TANGENT: {134if (!(p_surface.format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES)) {135stride += sizeof(uint16_t) * 2;136}137} break;138case RS::ARRAY_COLOR: {139attrib_stride += sizeof(uint32_t);140} break;141case RS::ARRAY_TEX_UV: {142if (p_surface.format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES) {143attrib_stride += sizeof(uint16_t) * 2;144} else {145attrib_stride += sizeof(float) * 2;146}147} break;148case RS::ARRAY_TEX_UV2: {149if (p_surface.format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES) {150attrib_stride += sizeof(uint16_t) * 2;151} else {152attrib_stride += sizeof(float) * 2;153}154} break;155case RS::ARRAY_CUSTOM0:156case RS::ARRAY_CUSTOM1:157case RS::ARRAY_CUSTOM2:158case RS::ARRAY_CUSTOM3: {159int idx = i - RS::ARRAY_CUSTOM0;160uint32_t fmt_shift[RS::ARRAY_CUSTOM_COUNT] = { RS::ARRAY_FORMAT_CUSTOM0_SHIFT, RS::ARRAY_FORMAT_CUSTOM1_SHIFT, RS::ARRAY_FORMAT_CUSTOM2_SHIFT, RS::ARRAY_FORMAT_CUSTOM3_SHIFT };161uint32_t fmt = (p_surface.format >> fmt_shift[idx]) & RS::ARRAY_FORMAT_CUSTOM_MASK;162uint32_t fmtsize[RS::ARRAY_CUSTOM_MAX] = { 4, 4, 4, 8, 4, 8, 12, 16 };163attrib_stride += fmtsize[fmt];164165} break;166case RS::ARRAY_WEIGHTS:167case RS::ARRAY_BONES: {168//uses a separate array169bool use_8 = p_surface.format & RS::ARRAY_FLAG_USE_8_BONE_WEIGHTS;170skin_stride += sizeof(int16_t) * (use_8 ? 16 : 8);171} break;172}173}174}175176int expected_size = stride * p_surface.vertex_count;177ERR_FAIL_COND_MSG(expected_size != p_surface.vertex_data.size(), "Size of vertex data provided (" + itos(p_surface.vertex_data.size()) + ") does not match expected (" + itos(expected_size) + ")");178179int bs_expected_size = expected_size * mesh->blend_shape_count;180181ERR_FAIL_COND_MSG(bs_expected_size != p_surface.blend_shape_data.size(), "Size of blend shape data provided (" + itos(p_surface.blend_shape_data.size()) + ") does not match expected (" + itos(bs_expected_size) + ")");182183int expected_attrib_size = attrib_stride * p_surface.vertex_count;184ERR_FAIL_COND_MSG(expected_attrib_size != p_surface.attribute_data.size(), "Size of attribute data provided (" + itos(p_surface.attribute_data.size()) + ") does not match expected (" + itos(expected_attrib_size) + ")");185186if ((p_surface.format & RS::ARRAY_FORMAT_WEIGHTS) && (p_surface.format & RS::ARRAY_FORMAT_BONES)) {187expected_size = skin_stride * p_surface.vertex_count;188ERR_FAIL_COND_MSG(expected_size != p_surface.skin_data.size(), "Size of skin data provided (" + itos(p_surface.skin_data.size()) + ") does not match expected (" + itos(expected_size) + ")");189}190}191192#endif193194uint64_t surface_version = p_surface.format & (uint64_t(RS::ARRAY_FLAG_FORMAT_VERSION_MASK) << RS::ARRAY_FLAG_FORMAT_VERSION_SHIFT);195RS::SurfaceData new_surface = p_surface;196#ifdef DISABLE_DEPRECATED197198ERR_FAIL_COND_MSG(surface_version != RS::ARRAY_FLAG_FORMAT_CURRENT_VERSION, "Surface version provided (" + itos(int(surface_version >> RS::ARRAY_FLAG_FORMAT_VERSION_SHIFT)) + ") does not match current version (" + itos(RS::ARRAY_FLAG_FORMAT_CURRENT_VERSION >> RS::ARRAY_FLAG_FORMAT_VERSION_SHIFT) + ")");199200#else201202if (surface_version != uint64_t(RS::ARRAY_FLAG_FORMAT_CURRENT_VERSION)) {203RS::get_singleton()->fix_surface_compatibility(new_surface);204surface_version = new_surface.format & (uint64_t(RS::ARRAY_FLAG_FORMAT_VERSION_MASK) << RS::ARRAY_FLAG_FORMAT_VERSION_SHIFT);205ERR_FAIL_COND_MSG(surface_version != RS::ARRAY_FLAG_FORMAT_CURRENT_VERSION,206vformat("Surface version provided (%d) does not match current version (%d).",207(surface_version >> RS::ARRAY_FLAG_FORMAT_VERSION_SHIFT) & RS::ARRAY_FLAG_FORMAT_VERSION_MASK,208(RS::ARRAY_FLAG_FORMAT_CURRENT_VERSION >> RS::ARRAY_FLAG_FORMAT_VERSION_SHIFT) & RS::ARRAY_FLAG_FORMAT_VERSION_MASK));209}210#endif211212Mesh::Surface *s = memnew(Mesh::Surface);213214s->format = new_surface.format;215s->primitive = new_surface.primitive;216217if (new_surface.vertex_data.size()) {218glGenBuffers(1, &s->vertex_buffer);219glBindBuffer(GL_ARRAY_BUFFER, s->vertex_buffer);220// If we have an uncompressed surface that contains normals, but not tangents, we need to differentiate the array221// from a compressed array in the shader. To do so, we allow the normal to read 4 components out of the buffer222// But only give it 2 components per normal. So essentially, each vertex reads the next normal in normal.zw.223// This allows us to avoid adding a shader permutation, and avoid passing dummy tangents. Since the stride is kept small224// this should still be a net win for bandwidth.225// If we do this, then the last normal will read past the end of the array. So we need to pad the array with dummy data.226if (!(new_surface.format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES) && (new_surface.format & RS::ARRAY_FORMAT_NORMAL) && !(new_surface.format & RS::ARRAY_FORMAT_TANGENT)) {227// Unfortunately, we need to copy the buffer, which is fine as doing a resize triggers a CoW anyway.228Vector<uint8_t> new_vertex_data;229new_vertex_data.resize_initialized(new_surface.vertex_data.size() + sizeof(uint16_t) * 2);230memcpy(new_vertex_data.ptrw(), new_surface.vertex_data.ptr(), new_surface.vertex_data.size());231GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s->vertex_buffer, new_vertex_data.size(), new_vertex_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW, "Mesh vertex buffer");232s->vertex_buffer_size = new_vertex_data.size();233} else {234GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s->vertex_buffer, new_surface.vertex_data.size(), new_surface.vertex_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW, "Mesh vertex buffer");235s->vertex_buffer_size = new_surface.vertex_data.size();236}237}238239if (new_surface.attribute_data.size()) {240glGenBuffers(1, &s->attribute_buffer);241glBindBuffer(GL_ARRAY_BUFFER, s->attribute_buffer);242GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s->attribute_buffer, new_surface.attribute_data.size(), new_surface.attribute_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW, "Mesh attribute buffer");243s->attribute_buffer_size = new_surface.attribute_data.size();244}245246if (new_surface.skin_data.size()) {247glGenBuffers(1, &s->skin_buffer);248glBindBuffer(GL_ARRAY_BUFFER, s->skin_buffer);249GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s->skin_buffer, new_surface.skin_data.size(), new_surface.skin_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW, "Mesh skin buffer");250s->skin_buffer_size = new_surface.skin_data.size();251}252253glBindBuffer(GL_ARRAY_BUFFER, 0);254255s->vertex_count = new_surface.vertex_count;256257if (new_surface.format & RS::ARRAY_FORMAT_BONES) {258mesh->has_bone_weights = true;259}260261if (new_surface.index_count) {262bool is_index_16 = new_surface.vertex_count <= 65536 && new_surface.vertex_count > 0;263glGenBuffers(1, &s->index_buffer);264glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->index_buffer);265GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ELEMENT_ARRAY_BUFFER, s->index_buffer, new_surface.index_data.size(), new_surface.index_data.ptr(), GL_STATIC_DRAW, "Mesh index buffer");266glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind267s->index_count = new_surface.index_count;268s->index_buffer_size = new_surface.index_data.size();269270if (new_surface.lods.size()) {271s->lods = memnew_arr(Mesh::Surface::LOD, new_surface.lods.size());272s->lod_count = new_surface.lods.size();273274for (int i = 0; i < new_surface.lods.size(); i++) {275glGenBuffers(1, &s->lods[i].index_buffer);276glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->lods[i].index_buffer);277GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ELEMENT_ARRAY_BUFFER, s->lods[i].index_buffer, new_surface.lods[i].index_data.size(), new_surface.lods[i].index_data.ptr(), GL_STATIC_DRAW, "Mesh index buffer LOD[" + itos(i) + "]");278glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind279s->lods[i].edge_length = new_surface.lods[i].edge_length;280s->lods[i].index_count = new_surface.lods[i].index_data.size() / (is_index_16 ? 2 : 4);281s->lods[i].index_buffer_size = new_surface.lods[i].index_data.size();282}283}284}285286ERR_FAIL_COND_MSG(!new_surface.index_count && !new_surface.vertex_count, "Meshes must contain a vertex array, an index array, or both");287288if (GLES3::Config::get_singleton()->generate_wireframes && s->primitive == RS::PRIMITIVE_TRIANGLES) {289// Generate wireframes. This is mostly used by the editor.290s->wireframe = memnew(Mesh::Surface::Wireframe);291Vector<uint32_t> wf_indices;292uint32_t &wf_index_count = s->wireframe->index_count;293uint32_t *wr = nullptr;294295if (new_surface.format & RS::ARRAY_FORMAT_INDEX) {296wf_index_count = s->index_count * 2;297wf_indices.resize(wf_index_count);298299Vector<uint8_t> ir = new_surface.index_data;300wr = wf_indices.ptrw();301302if (new_surface.vertex_count <= 65536) {303// Read 16 bit indices.304const uint16_t *src_idx = (const uint16_t *)ir.ptr();305for (uint32_t i = 0; i + 5 < wf_index_count; i += 6) {306// We use GL_LINES instead of GL_TRIANGLES for drawing these primitives later,307// so we need double the indices for each triangle.308wr[i + 0] = src_idx[i / 2];309wr[i + 1] = src_idx[i / 2 + 1];310wr[i + 2] = src_idx[i / 2 + 1];311wr[i + 3] = src_idx[i / 2 + 2];312wr[i + 4] = src_idx[i / 2 + 2];313wr[i + 5] = src_idx[i / 2];314}315316} else {317// Read 32 bit indices.318const uint32_t *src_idx = (const uint32_t *)ir.ptr();319for (uint32_t i = 0; i + 5 < wf_index_count; i += 6) {320wr[i + 0] = src_idx[i / 2];321wr[i + 1] = src_idx[i / 2 + 1];322wr[i + 2] = src_idx[i / 2 + 1];323wr[i + 3] = src_idx[i / 2 + 2];324wr[i + 4] = src_idx[i / 2 + 2];325wr[i + 5] = src_idx[i / 2];326}327}328} else {329// Not using indices.330wf_index_count = s->vertex_count * 2;331wf_indices.resize(wf_index_count);332wr = wf_indices.ptrw();333334for (uint32_t i = 0; i + 5 < wf_index_count; i += 6) {335wr[i + 0] = i / 2;336wr[i + 1] = i / 2 + 1;337wr[i + 2] = i / 2 + 1;338wr[i + 3] = i / 2 + 2;339wr[i + 4] = i / 2 + 2;340wr[i + 5] = i / 2;341}342}343344s->wireframe->index_buffer_size = wf_index_count * sizeof(uint32_t);345glGenBuffers(1, &s->wireframe->index_buffer);346glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->wireframe->index_buffer);347GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ELEMENT_ARRAY_BUFFER, s->wireframe->index_buffer, s->wireframe->index_buffer_size, wr, GL_STATIC_DRAW, "Mesh wireframe index buffer");348glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // unbind349}350351s->aabb = new_surface.aabb;352s->bone_aabbs = new_surface.bone_aabbs; //only really useful for returning them.353s->mesh_to_skeleton_xform = p_surface.mesh_to_skeleton_xform;354355s->uv_scale = new_surface.uv_scale;356357if (new_surface.skin_data.size() || mesh->blend_shape_count > 0) {358// Size must match the size of the vertex array.359int size = new_surface.vertex_data.size();360int vertex_size = 0;361int position_stride = 0;362int normal_tangent_stride = 0;363int normal_offset = 0;364int tangent_offset = 0;365if ((new_surface.format & (1ULL << RS::ARRAY_VERTEX))) {366if (new_surface.format & RS::ARRAY_FLAG_USE_2D_VERTICES) {367vertex_size = 2;368position_stride = sizeof(float) * vertex_size;369} else {370if (new_surface.format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES) {371vertex_size = 4;372position_stride = sizeof(uint16_t) * vertex_size;373} else {374vertex_size = 3;375position_stride = sizeof(float) * vertex_size;376}377}378}379if ((new_surface.format & (1ULL << RS::ARRAY_NORMAL))) {380normal_offset = position_stride * s->vertex_count;381normal_tangent_stride += sizeof(uint16_t) * 2;382}383if ((new_surface.format & (1ULL << RS::ARRAY_TANGENT))) {384tangent_offset = normal_offset + normal_tangent_stride;385normal_tangent_stride += sizeof(uint16_t) * 2;386}387388if (mesh->blend_shape_count > 0) {389// Blend shapes are passed as one large array, for OpenGL, we need to split each of them into their own buffer390s->blend_shapes = memnew_arr(Mesh::Surface::BlendShape, mesh->blend_shape_count);391392for (uint32_t i = 0; i < mesh->blend_shape_count; i++) {393glGenVertexArrays(1, &s->blend_shapes[i].vertex_array);394glBindVertexArray(s->blend_shapes[i].vertex_array);395glGenBuffers(1, &s->blend_shapes[i].vertex_buffer);396glBindBuffer(GL_ARRAY_BUFFER, s->blend_shapes[i].vertex_buffer);397GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s->blend_shapes[i].vertex_buffer, size, new_surface.blend_shape_data.ptr() + i * size, (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW, "Mesh blend shape buffer");398399if ((new_surface.format & (1ULL << RS::ARRAY_VERTEX))) {400glEnableVertexAttribArray(RS::ARRAY_VERTEX + 3);401glVertexAttribPointer(RS::ARRAY_VERTEX + 3, vertex_size, GL_FLOAT, GL_FALSE, position_stride, CAST_INT_TO_UCHAR_PTR(0));402}403if ((new_surface.format & (1ULL << RS::ARRAY_NORMAL))) {404// Normal and tangent are packed into the same attribute.405glEnableVertexAttribArray(RS::ARRAY_NORMAL + 3);406glVertexAttribPointer(RS::ARRAY_NORMAL + 3, 2, GL_UNSIGNED_SHORT, GL_TRUE, normal_tangent_stride, CAST_INT_TO_UCHAR_PTR(normal_offset));407}408if ((p_surface.format & (1ULL << RS::ARRAY_TANGENT))) {409glEnableVertexAttribArray(RS::ARRAY_TANGENT + 3);410glVertexAttribPointer(RS::ARRAY_TANGENT + 3, 2, GL_UNSIGNED_SHORT, GL_TRUE, normal_tangent_stride, CAST_INT_TO_UCHAR_PTR(tangent_offset));411}412}413glBindVertexArray(0);414glBindBuffer(GL_ARRAY_BUFFER, 0);415}416417glBindVertexArray(0);418glBindBuffer(GL_ARRAY_BUFFER, 0);419}420421if (mesh->surface_count == 0) {422mesh->aabb = new_surface.aabb;423} else {424mesh->aabb.merge_with(new_surface.aabb);425}426mesh->skeleton_aabb_version = 0;427428s->material = new_surface.material;429430mesh->surfaces = (Mesh::Surface **)memrealloc(mesh->surfaces, sizeof(Mesh::Surface *) * (mesh->surface_count + 1));431mesh->surfaces[mesh->surface_count] = s;432mesh->surface_count++;433434for (MeshInstance *mi : mesh->instances) {435_mesh_instance_add_surface(mi, mesh, mesh->surface_count - 1);436}437438mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);439440for (Mesh *E : mesh->shadow_owners) {441Mesh *shadow_owner = E;442shadow_owner->shadow_mesh = RID();443shadow_owner->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);444}445446mesh->material_cache.clear();447}448449void MeshStorage::_mesh_surface_clear(Mesh *mesh, int p_surface) {450Mesh::Surface &s = *mesh->surfaces[p_surface];451452if (s.vertex_buffer != 0) {453GLES3::Utilities::get_singleton()->buffer_free_data(s.vertex_buffer);454s.vertex_buffer = 0;455}456457if (s.version_count != 0) {458for (uint32_t j = 0; j < s.version_count; j++) {459glDeleteVertexArrays(1, &s.versions[j].vertex_array);460s.versions[j].vertex_array = 0;461}462}463464if (s.attribute_buffer != 0) {465GLES3::Utilities::get_singleton()->buffer_free_data(s.attribute_buffer);466s.attribute_buffer = 0;467}468469if (s.skin_buffer != 0) {470GLES3::Utilities::get_singleton()->buffer_free_data(s.skin_buffer);471s.skin_buffer = 0;472}473474if (s.index_buffer != 0) {475GLES3::Utilities::get_singleton()->buffer_free_data(s.index_buffer);476s.index_buffer = 0;477}478479if (s.versions) {480memfree(s.versions); // reallocs, so free with memfree.481}482483if (s.wireframe) {484GLES3::Utilities::get_singleton()->buffer_free_data(s.wireframe->index_buffer);485memdelete(s.wireframe);486}487488if (s.lod_count) {489for (uint32_t j = 0; j < s.lod_count; j++) {490if (s.lods[j].index_buffer != 0) {491GLES3::Utilities::get_singleton()->buffer_free_data(s.lods[j].index_buffer);492s.lods[j].index_buffer = 0;493}494}495memdelete_arr(s.lods);496}497498if (mesh->blend_shape_count) {499for (uint32_t j = 0; j < mesh->blend_shape_count; j++) {500if (s.blend_shapes[j].vertex_buffer != 0) {501GLES3::Utilities::get_singleton()->buffer_free_data(s.blend_shapes[j].vertex_buffer);502s.blend_shapes[j].vertex_buffer = 0;503}504if (s.blend_shapes[j].vertex_array != 0) {505glDeleteVertexArrays(1, &s.blend_shapes[j].vertex_array);506s.blend_shapes[j].vertex_array = 0;507}508}509memdelete_arr(s.blend_shapes);510}511512memdelete(mesh->surfaces[p_surface]);513}514515int MeshStorage::mesh_get_blend_shape_count(RID p_mesh) const {516const Mesh *mesh = mesh_owner.get_or_null(p_mesh);517ERR_FAIL_NULL_V(mesh, -1);518return mesh->blend_shape_count;519}520521void MeshStorage::mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) {522Mesh *mesh = mesh_owner.get_or_null(p_mesh);523ERR_FAIL_NULL(mesh);524ERR_FAIL_INDEX((int)p_mode, 2);525526mesh->blend_shape_mode = p_mode;527}528529RS::BlendShapeMode MeshStorage::mesh_get_blend_shape_mode(RID p_mesh) const {530Mesh *mesh = mesh_owner.get_or_null(p_mesh);531ERR_FAIL_NULL_V(mesh, RS::BLEND_SHAPE_MODE_NORMALIZED);532return mesh->blend_shape_mode;533}534535void MeshStorage::mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) {536ERR_FAIL_COND(p_data.is_empty());537Mesh *mesh = mesh_owner.get_or_null(p_mesh);538ERR_FAIL_NULL(mesh);539ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count);540541uint64_t data_size = p_data.size();542ERR_FAIL_COND(p_offset + data_size > mesh->surfaces[p_surface]->vertex_buffer_size);543const uint8_t *r = p_data.ptr();544545glBindBuffer(GL_ARRAY_BUFFER, mesh->surfaces[p_surface]->vertex_buffer);546glBufferSubData(GL_ARRAY_BUFFER, p_offset, data_size, r);547glBindBuffer(GL_ARRAY_BUFFER, 0);548}549550void MeshStorage::mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) {551ERR_FAIL_COND(p_data.is_empty());552Mesh *mesh = mesh_owner.get_or_null(p_mesh);553ERR_FAIL_NULL(mesh);554ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count);555556uint64_t data_size = p_data.size();557ERR_FAIL_COND(p_offset + data_size > mesh->surfaces[p_surface]->attribute_buffer_size);558const uint8_t *r = p_data.ptr();559560glBindBuffer(GL_ARRAY_BUFFER, mesh->surfaces[p_surface]->attribute_buffer);561glBufferSubData(GL_ARRAY_BUFFER, p_offset, data_size, r);562glBindBuffer(GL_ARRAY_BUFFER, 0);563}564565void MeshStorage::mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) {566ERR_FAIL_COND(p_data.is_empty());567Mesh *mesh = mesh_owner.get_or_null(p_mesh);568ERR_FAIL_NULL(mesh);569ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count);570571uint64_t data_size = p_data.size();572ERR_FAIL_COND(p_offset + data_size > mesh->surfaces[p_surface]->skin_buffer_size);573const uint8_t *r = p_data.ptr();574575glBindBuffer(GL_ARRAY_BUFFER, mesh->surfaces[p_surface]->skin_buffer);576glBufferSubData(GL_ARRAY_BUFFER, p_offset, data_size, r);577glBindBuffer(GL_ARRAY_BUFFER, 0);578}579580void MeshStorage::mesh_surface_update_index_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) {581ERR_FAIL_COND(p_data.is_empty());582Mesh *mesh = mesh_owner.get_or_null(p_mesh);583ERR_FAIL_NULL(mesh);584ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count);585586uint64_t data_size = p_data.size();587ERR_FAIL_COND(p_offset + data_size > mesh->surfaces[p_surface]->index_buffer_size);588const uint8_t *r = p_data.ptr();589590glBindBuffer(GL_ARRAY_BUFFER, mesh->surfaces[p_surface]->index_buffer);591glBufferSubData(GL_ARRAY_BUFFER, p_offset, data_size, r);592glBindBuffer(GL_ARRAY_BUFFER, 0);593}594595void MeshStorage::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) {596Mesh *mesh = mesh_owner.get_or_null(p_mesh);597ERR_FAIL_NULL(mesh);598ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count);599mesh->surfaces[p_surface]->material = p_material;600601mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL);602mesh->material_cache.clear();603}604605RID MeshStorage::mesh_surface_get_material(RID p_mesh, int p_surface) const {606Mesh *mesh = mesh_owner.get_or_null(p_mesh);607ERR_FAIL_NULL_V(mesh, RID());608ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_surface, mesh->surface_count, RID());609610return mesh->surfaces[p_surface]->material;611}612613RS::SurfaceData MeshStorage::mesh_get_surface(RID p_mesh, int p_surface) const {614Mesh *mesh = mesh_owner.get_or_null(p_mesh);615ERR_FAIL_NULL_V(mesh, RS::SurfaceData());616ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_surface, mesh->surface_count, RS::SurfaceData());617618Mesh::Surface &s = *mesh->surfaces[p_surface];619620RS::SurfaceData sd;621sd.format = s.format;622if (s.vertex_buffer != 0) {623sd.vertex_data = Utilities::buffer_get_data(GL_ARRAY_BUFFER, s.vertex_buffer, s.vertex_buffer_size);624625// When using an uncompressed buffer with normals, but without tangents, we have to trim the padding.626if (!(s.format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES) && (s.format & RS::ARRAY_FORMAT_NORMAL) && !(s.format & RS::ARRAY_FORMAT_TANGENT)) {627sd.vertex_data.resize(sd.vertex_data.size() - sizeof(uint16_t) * 2);628}629}630631if (s.attribute_buffer != 0) {632sd.attribute_data = Utilities::buffer_get_data(GL_ARRAY_BUFFER, s.attribute_buffer, s.attribute_buffer_size);633}634635if (s.skin_buffer != 0) {636sd.skin_data = Utilities::buffer_get_data(GL_ARRAY_BUFFER, s.skin_buffer, s.skin_buffer_size);637}638639sd.vertex_count = s.vertex_count;640sd.index_count = s.index_count;641sd.primitive = s.primitive;642643if (sd.index_count) {644sd.index_data = Utilities::buffer_get_data(GL_ELEMENT_ARRAY_BUFFER, s.index_buffer, s.index_buffer_size);645}646647sd.aabb = s.aabb;648for (uint32_t i = 0; i < s.lod_count; i++) {649RS::SurfaceData::LOD lod;650lod.edge_length = s.lods[i].edge_length;651lod.index_data = Utilities::buffer_get_data(GL_ELEMENT_ARRAY_BUFFER, s.lods[i].index_buffer, s.lods[i].index_buffer_size);652sd.lods.push_back(lod);653}654655sd.bone_aabbs = s.bone_aabbs;656sd.mesh_to_skeleton_xform = s.mesh_to_skeleton_xform;657658if (mesh->blend_shape_count) {659sd.blend_shape_data = Vector<uint8_t>();660for (uint32_t i = 0; i < mesh->blend_shape_count; i++) {661sd.blend_shape_data.append_array(Utilities::buffer_get_data(GL_ARRAY_BUFFER, s.blend_shapes[i].vertex_buffer, s.vertex_buffer_size));662}663}664665sd.uv_scale = s.uv_scale;666667return sd;668}669670int MeshStorage::mesh_get_surface_count(RID p_mesh) const {671Mesh *mesh = mesh_owner.get_or_null(p_mesh);672ERR_FAIL_NULL_V(mesh, 0);673return mesh->surface_count;674}675676void MeshStorage::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) {677Mesh *mesh = mesh_owner.get_or_null(p_mesh);678ERR_FAIL_NULL(mesh);679mesh->custom_aabb = p_aabb;680681mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);682}683684AABB MeshStorage::mesh_get_custom_aabb(RID p_mesh) const {685Mesh *mesh = mesh_owner.get_or_null(p_mesh);686ERR_FAIL_NULL_V(mesh, AABB());687return mesh->custom_aabb;688}689690AABB MeshStorage::mesh_get_aabb(RID p_mesh, RID p_skeleton) {691Mesh *mesh = mesh_owner.get_or_null(p_mesh);692ERR_FAIL_NULL_V(mesh, AABB());693694if (mesh->custom_aabb != AABB()) {695return mesh->custom_aabb;696}697698Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);699700if (!skeleton || skeleton->size == 0 || mesh->skeleton_aabb_version == skeleton->version) {701return mesh->aabb;702}703704// Calculate AABB based on Skeleton705706AABB aabb;707708for (uint32_t i = 0; i < mesh->surface_count; i++) {709AABB laabb;710const Mesh::Surface &surface = *mesh->surfaces[i];711if ((surface.format & RS::ARRAY_FORMAT_BONES) && surface.bone_aabbs.size()) {712int bs = surface.bone_aabbs.size();713const AABB *skbones = surface.bone_aabbs.ptr();714715int sbs = skeleton->size;716ERR_CONTINUE(bs > sbs);717const float *baseptr = skeleton->data.ptr();718719bool found_bone_aabb = false;720721if (skeleton->use_2d) {722for (int j = 0; j < bs; j++) {723if (skbones[j].size == Vector3(-1, -1, -1)) {724continue; //bone is unused725}726727const float *dataptr = baseptr + j * 8;728729Transform3D mtx;730731mtx.basis.rows[0][0] = dataptr[0];732mtx.basis.rows[0][1] = dataptr[1];733mtx.origin.x = dataptr[3];734735mtx.basis.rows[1][0] = dataptr[4];736mtx.basis.rows[1][1] = dataptr[5];737mtx.origin.y = dataptr[7];738739// Transform bounds to skeleton's space before applying animation data.740AABB baabb = surface.mesh_to_skeleton_xform.xform(skbones[j]);741baabb = mtx.xform(baabb);742743if (!found_bone_aabb) {744laabb = baabb;745found_bone_aabb = true;746} else {747laabb.merge_with(baabb);748}749}750} else {751for (int j = 0; j < bs; j++) {752if (skbones[j].size == Vector3(-1, -1, -1)) {753continue; //bone is unused754}755756const float *dataptr = baseptr + j * 12;757758Transform3D mtx;759760mtx.basis.rows[0][0] = dataptr[0];761mtx.basis.rows[0][1] = dataptr[1];762mtx.basis.rows[0][2] = dataptr[2];763mtx.origin.x = dataptr[3];764mtx.basis.rows[1][0] = dataptr[4];765mtx.basis.rows[1][1] = dataptr[5];766mtx.basis.rows[1][2] = dataptr[6];767mtx.origin.y = dataptr[7];768mtx.basis.rows[2][0] = dataptr[8];769mtx.basis.rows[2][1] = dataptr[9];770mtx.basis.rows[2][2] = dataptr[10];771mtx.origin.z = dataptr[11];772773// Transform bounds to skeleton's space before applying animation data.774AABB baabb = surface.mesh_to_skeleton_xform.xform(skbones[j]);775baabb = mtx.xform(baabb);776777if (!found_bone_aabb) {778laabb = baabb;779found_bone_aabb = true;780} else {781laabb.merge_with(baabb);782}783}784}785786if (found_bone_aabb) {787// Transform skeleton bounds back to mesh's space if any animated AABB applied.788laabb = surface.mesh_to_skeleton_xform.affine_inverse().xform(laabb);789}790791if (laabb.size == Vector3()) {792laabb = surface.aabb;793}794} else {795laabb = surface.aabb;796}797798if (i == 0) {799aabb = laabb;800} else {801aabb.merge_with(laabb);802}803}804805mesh->aabb = aabb;806mesh->skeleton_aabb_version = skeleton->version;807return aabb;808}809810void MeshStorage::mesh_set_path(RID p_mesh, const String &p_path) {811Mesh *mesh = mesh_owner.get_or_null(p_mesh);812ERR_FAIL_NULL(mesh);813814mesh->path = p_path;815}816817String MeshStorage::mesh_get_path(RID p_mesh) const {818Mesh *mesh = mesh_owner.get_or_null(p_mesh);819ERR_FAIL_NULL_V(mesh, String());820821return mesh->path;822}823824void MeshStorage::mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) {825ERR_FAIL_COND_MSG(p_mesh == p_shadow_mesh, "Cannot set a mesh as its own shadow mesh.");826Mesh *mesh = mesh_owner.get_or_null(p_mesh);827ERR_FAIL_NULL(mesh);828829Mesh *shadow_mesh = mesh_owner.get_or_null(mesh->shadow_mesh);830if (shadow_mesh) {831shadow_mesh->shadow_owners.erase(mesh);832}833mesh->shadow_mesh = p_shadow_mesh;834835shadow_mesh = mesh_owner.get_or_null(mesh->shadow_mesh);836837if (shadow_mesh) {838shadow_mesh->shadow_owners.insert(mesh);839}840841mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);842}843844void MeshStorage::mesh_clear(RID p_mesh) {845Mesh *mesh = mesh_owner.get_or_null(p_mesh);846ERR_FAIL_NULL(mesh);847848// Clear instance data before mesh data.849for (MeshInstance *mi : mesh->instances) {850_mesh_instance_clear(mi);851}852853for (uint32_t i = 0; i < mesh->surface_count; i++) {854_mesh_surface_clear(mesh, i);855}856if (mesh->surfaces) {857memfree(mesh->surfaces);858}859860mesh->surfaces = nullptr;861mesh->surface_count = 0;862mesh->material_cache.clear();863mesh->has_bone_weights = false;864mesh->aabb = AABB();865mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);866867for (Mesh *E : mesh->shadow_owners) {868Mesh *shadow_owner = E;869shadow_owner->shadow_mesh = RID();870shadow_owner->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);871}872}873874void MeshStorage::_mesh_surface_generate_version_for_input_mask(Mesh::Surface::Version &v, Mesh::Surface *s, uint64_t p_input_mask, MeshInstance::Surface *mis) {875Mesh::Surface::Attrib attribs[RS::ARRAY_MAX];876877int position_stride = 0; // Vertex position only.878int normal_tangent_stride = 0;879int attributes_stride = 0;880int skin_stride = 0;881882for (int i = 0; i < RS::ARRAY_INDEX; i++) {883attribs[i].enabled = false;884attribs[i].integer = false;885if (!(s->format & (1ULL << i))) {886continue;887}888889if ((p_input_mask & (1ULL << i))) {890// Only enable if it matches input mask.891// Iterate over all anyway, so we can calculate stride.892attribs[i].enabled = true;893}894895switch (i) {896case RS::ARRAY_VERTEX: {897attribs[i].offset = 0;898attribs[i].type = GL_FLOAT;899attribs[i].normalized = GL_FALSE;900if (s->format & RS::ARRAY_FLAG_USE_2D_VERTICES) {901attribs[i].size = 2;902position_stride = attribs[i].size * sizeof(float);903} else {904if (!mis && (s->format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES)) {905attribs[i].size = 4;906position_stride = attribs[i].size * sizeof(uint16_t);907attribs[i].type = GL_UNSIGNED_SHORT;908attribs[i].normalized = GL_TRUE;909} else {910attribs[i].size = 3;911position_stride = attribs[i].size * sizeof(float);912}913}914} break;915case RS::ARRAY_NORMAL: {916if (!mis && (s->format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES)) {917attribs[i].size = 2;918normal_tangent_stride += 2 * attribs[i].size;919} else {920attribs[i].size = 4;921// A small trick here: if we are uncompressed and we have normals, but no tangents. We need922// the shader to think there are 4 components to "axis_tangent_attrib". So we give a size of 4,923// but a stride based on only having 2 elements.924if (!(s->format & RS::ARRAY_FORMAT_TANGENT)) {925normal_tangent_stride += (mis ? sizeof(float) : sizeof(uint16_t)) * 2;926} else {927normal_tangent_stride += (mis ? sizeof(float) : sizeof(uint16_t)) * 4;928}929}930931if (mis) {932// Transform feedback has interleave all or no attributes. It can't mix interleaving.933attribs[i].offset = position_stride;934normal_tangent_stride += position_stride;935position_stride = normal_tangent_stride;936} else {937attribs[i].offset = position_stride * s->vertex_count;938}939attribs[i].type = (mis ? GL_FLOAT : GL_UNSIGNED_SHORT);940attribs[i].normalized = GL_TRUE;941} break;942case RS::ARRAY_TANGENT: {943// We never use the tangent attribute. It is always packed in ARRAY_NORMAL, or ARRAY_VERTEX.944attribs[i].enabled = false;945attribs[i].integer = false;946} break;947case RS::ARRAY_COLOR: {948attribs[i].offset = attributes_stride;949attribs[i].size = 4;950attribs[i].type = GL_UNSIGNED_BYTE;951attributes_stride += 4;952attribs[i].normalized = GL_TRUE;953} break;954case RS::ARRAY_TEX_UV: {955attribs[i].offset = attributes_stride;956attribs[i].size = 2;957if (s->format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES) {958attribs[i].type = GL_UNSIGNED_SHORT;959attributes_stride += 2 * sizeof(uint16_t);960attribs[i].normalized = GL_TRUE;961} else {962attribs[i].type = GL_FLOAT;963attributes_stride += 2 * sizeof(float);964attribs[i].normalized = GL_FALSE;965}966} break;967case RS::ARRAY_TEX_UV2: {968attribs[i].offset = attributes_stride;969attribs[i].size = 2;970if (s->format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES) {971attribs[i].type = GL_UNSIGNED_SHORT;972attributes_stride += 2 * sizeof(uint16_t);973attribs[i].normalized = GL_TRUE;974} else {975attribs[i].type = GL_FLOAT;976attributes_stride += 2 * sizeof(float);977attribs[i].normalized = GL_FALSE;978}979} break;980case RS::ARRAY_CUSTOM0:981case RS::ARRAY_CUSTOM1:982case RS::ARRAY_CUSTOM2:983case RS::ARRAY_CUSTOM3: {984attribs[i].offset = attributes_stride;985986int idx = i - RS::ARRAY_CUSTOM0;987uint32_t fmt_shift[RS::ARRAY_CUSTOM_COUNT] = { RS::ARRAY_FORMAT_CUSTOM0_SHIFT, RS::ARRAY_FORMAT_CUSTOM1_SHIFT, RS::ARRAY_FORMAT_CUSTOM2_SHIFT, RS::ARRAY_FORMAT_CUSTOM3_SHIFT };988uint32_t fmt = (s->format >> fmt_shift[idx]) & RS::ARRAY_FORMAT_CUSTOM_MASK;989uint32_t fmtsize[RS::ARRAY_CUSTOM_MAX] = { 4, 4, 4, 8, 4, 8, 12, 16 };990GLenum gl_type[RS::ARRAY_CUSTOM_MAX] = { GL_UNSIGNED_BYTE, GL_BYTE, GL_HALF_FLOAT, GL_HALF_FLOAT, GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_FLOAT };991GLboolean norm[RS::ARRAY_CUSTOM_MAX] = { GL_TRUE, GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE };992attribs[i].type = gl_type[fmt];993attributes_stride += fmtsize[fmt];994attribs[i].size = fmtsize[fmt] / sizeof(float);995attribs[i].normalized = norm[fmt];996} break;997case RS::ARRAY_BONES: {998attribs[i].offset = skin_stride;999attribs[i].size = 4;1000attribs[i].type = GL_UNSIGNED_SHORT;1001skin_stride += 4 * sizeof(uint16_t);1002attribs[i].normalized = GL_FALSE;1003attribs[i].integer = true;1004} break;1005case RS::ARRAY_WEIGHTS: {1006attribs[i].offset = skin_stride;1007attribs[i].size = 4;1008attribs[i].type = GL_UNSIGNED_SHORT;1009skin_stride += 4 * sizeof(uint16_t);1010attribs[i].normalized = GL_TRUE;1011} break;1012}1013}10141015glGenVertexArrays(1, &v.vertex_array);1016glBindVertexArray(v.vertex_array);10171018for (int i = 0; i < RS::ARRAY_INDEX; i++) {1019if (!attribs[i].enabled) {1020glDisableVertexAttribArray(i);1021continue;1022}1023if (i <= RS::ARRAY_TANGENT) {1024attribs[i].stride = (i == RS::ARRAY_VERTEX) ? position_stride : normal_tangent_stride;1025if (mis) {1026glBindBuffer(GL_ARRAY_BUFFER, mis->vertex_buffer);1027} else {1028glBindBuffer(GL_ARRAY_BUFFER, s->vertex_buffer);1029}1030} else if (i <= RS::ARRAY_CUSTOM3) {1031attribs[i].stride = attributes_stride;1032glBindBuffer(GL_ARRAY_BUFFER, s->attribute_buffer);1033} else {1034attribs[i].stride = skin_stride;1035glBindBuffer(GL_ARRAY_BUFFER, s->skin_buffer);1036}10371038if (attribs[i].integer) {1039glVertexAttribIPointer(i, attribs[i].size, attribs[i].type, attribs[i].stride, CAST_INT_TO_UCHAR_PTR(attribs[i].offset));1040} else {1041glVertexAttribPointer(i, attribs[i].size, attribs[i].type, attribs[i].normalized, attribs[i].stride, CAST_INT_TO_UCHAR_PTR(attribs[i].offset));1042}1043glEnableVertexAttribArray(i);1044}10451046// Do not bind index here as we want to switch between index buffers for LOD10471048glBindVertexArray(0);1049glBindBuffer(GL_ARRAY_BUFFER, 0);10501051v.input_mask = p_input_mask;1052}10531054void MeshStorage::mesh_surface_remove(RID p_mesh, int p_surface) {1055Mesh *mesh = mesh_owner.get_or_null(p_mesh);1056ERR_FAIL_NULL(mesh);1057ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count);10581059// Clear instance data before mesh data.1060for (MeshInstance *mi : mesh->instances) {1061_mesh_instance_remove_surface(mi, p_surface);1062}10631064_mesh_surface_clear(mesh, p_surface);10651066if ((uint32_t)p_surface < mesh->surface_count - 1) {1067memmove(mesh->surfaces + p_surface, mesh->surfaces + p_surface + 1, sizeof(Mesh::Surface *) * (mesh->surface_count - (p_surface + 1)));1068}1069mesh->surfaces = (Mesh::Surface **)memrealloc(mesh->surfaces, sizeof(Mesh::Surface *) * (mesh->surface_count - 1));1070--mesh->surface_count;10711072mesh->material_cache.clear();10731074mesh->skeleton_aabb_version = 0;10751076if (mesh->has_bone_weights) {1077mesh->has_bone_weights = false;1078for (uint32_t i = 0; i < mesh->surface_count; i++) {1079if (mesh->surfaces[i]->format & RS::ARRAY_FORMAT_BONES) {1080mesh->has_bone_weights = true;1081break;1082}1083}1084}10851086if (mesh->surface_count == 0) {1087mesh->aabb = AABB();1088} else {1089mesh->aabb = mesh->surfaces[0]->aabb;1090for (uint32_t i = 1; i < mesh->surface_count; i++) {1091mesh->aabb.merge_with(mesh->surfaces[i]->aabb);1092}1093}10941095mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);10961097for (Mesh *E : mesh->shadow_owners) {1098Mesh *shadow_owner = E;1099shadow_owner->shadow_mesh = RID();1100shadow_owner->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);1101}1102}11031104/* MESH INSTANCE API */11051106RID MeshStorage::mesh_instance_create(RID p_base) {1107Mesh *mesh = mesh_owner.get_or_null(p_base);1108ERR_FAIL_NULL_V(mesh, RID());11091110RID rid = mesh_instance_owner.make_rid();1111MeshInstance *mi = mesh_instance_owner.get_or_null(rid);11121113mi->mesh = mesh;11141115for (uint32_t i = 0; i < mesh->surface_count; i++) {1116_mesh_instance_add_surface(mi, mesh, i);1117}11181119mi->I = mesh->instances.push_back(mi);11201121mi->dirty = true;11221123return rid;1124}11251126void MeshStorage::mesh_instance_free(RID p_rid) {1127MeshInstance *mi = mesh_instance_owner.get_or_null(p_rid);1128_mesh_instance_clear(mi);1129mi->mesh->instances.erase(mi->I);1130mi->I = nullptr;11311132mesh_instance_owner.free(p_rid);1133}11341135void MeshStorage::mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) {1136MeshInstance *mi = mesh_instance_owner.get_or_null(p_mesh_instance);1137if (mi->skeleton == p_skeleton) {1138return;1139}1140mi->skeleton = p_skeleton;1141mi->skeleton_version = 0;1142mi->dirty = true;1143}11441145void MeshStorage::mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int p_shape, float p_weight) {1146MeshInstance *mi = mesh_instance_owner.get_or_null(p_mesh_instance);1147ERR_FAIL_NULL(mi);1148ERR_FAIL_INDEX(p_shape, (int)mi->blend_weights.size());1149mi->blend_weights[p_shape] = p_weight;1150mi->dirty = true;1151}11521153void MeshStorage::_mesh_instance_clear(MeshInstance *mi) {1154while (mi->surfaces.size()) {1155_mesh_instance_remove_surface(mi, mi->surfaces.size() - 1);1156}1157mi->dirty = false;1158}11591160void MeshStorage::_mesh_instance_add_surface(MeshInstance *mi, Mesh *mesh, uint32_t p_surface) {1161if (mesh->blend_shape_count > 0) {1162mi->blend_weights.resize(mesh->blend_shape_count);1163for (uint32_t i = 0; i < mi->blend_weights.size(); i++) {1164mi->blend_weights[i] = 0.0;1165}1166}11671168MeshInstance::Surface s;1169if ((mesh->blend_shape_count > 0 || (mesh->surfaces[p_surface]->format & RS::ARRAY_FORMAT_BONES)) && mesh->surfaces[p_surface]->vertex_buffer_size > 0) {1170// Cache surface properties1171s.format_cache = mesh->surfaces[p_surface]->format;1172if ((s.format_cache & (1ULL << RS::ARRAY_VERTEX))) {1173if (s.format_cache & RS::ARRAY_FLAG_USE_2D_VERTICES) {1174s.vertex_size_cache = 2;1175} else {1176s.vertex_size_cache = 3;1177}1178s.vertex_stride_cache = sizeof(float) * s.vertex_size_cache;1179}1180if ((s.format_cache & (1ULL << RS::ARRAY_NORMAL))) {1181s.vertex_normal_offset_cache = s.vertex_stride_cache;1182s.vertex_stride_cache += sizeof(uint32_t) * 2;1183}1184if ((s.format_cache & (1ULL << RS::ARRAY_TANGENT))) {1185s.vertex_tangent_offset_cache = s.vertex_stride_cache;1186s.vertex_stride_cache += sizeof(uint32_t) * 2;1187}11881189int buffer_size = s.vertex_stride_cache * mesh->surfaces[p_surface]->vertex_count;11901191// Buffer to be used for rendering. Final output of skeleton and blend shapes.1192glGenBuffers(1, &s.vertex_buffer);1193glBindBuffer(GL_ARRAY_BUFFER, s.vertex_buffer);1194GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s.vertex_buffer, buffer_size, nullptr, GL_DYNAMIC_DRAW, "MeshInstance vertex buffer");1195if (mesh->blend_shape_count > 0) {1196// Ping-Pong buffers for processing blendshapes.1197glGenBuffers(2, s.vertex_buffers);1198for (uint32_t i = 0; i < 2; i++) {1199glBindBuffer(GL_ARRAY_BUFFER, s.vertex_buffers[i]);1200GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s.vertex_buffers[i], buffer_size, nullptr, GL_DYNAMIC_DRAW, "MeshInstance process buffer[" + itos(i) + "]");1201}1202}1203glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind1204}12051206mi->surfaces.push_back(s);1207mi->dirty = true;1208}12091210void MeshStorage::_mesh_instance_remove_surface(MeshInstance *mi, int p_surface) {1211MeshInstance::Surface &surface = mi->surfaces[p_surface];12121213if (surface.version_count != 0) {1214for (uint32_t j = 0; j < surface.version_count; j++) {1215glDeleteVertexArrays(1, &surface.versions[j].vertex_array);1216surface.versions[j].vertex_array = 0;1217}1218memfree(surface.versions);1219}12201221if (surface.vertex_buffers[0] != 0) {1222GLES3::Utilities::get_singleton()->buffer_free_data(surface.vertex_buffers[0]);1223GLES3::Utilities::get_singleton()->buffer_free_data(surface.vertex_buffers[1]);1224surface.vertex_buffers[0] = 0;1225surface.vertex_buffers[1] = 0;1226}12271228if (surface.vertex_buffer != 0) {1229GLES3::Utilities::get_singleton()->buffer_free_data(surface.vertex_buffer);1230surface.vertex_buffer = 0;1231}12321233mi->surfaces.remove_at(p_surface);12341235if (mi->surfaces.is_empty()) {1236mi->blend_weights.clear();1237mi->weights_dirty = false;1238mi->skeleton_version = 0;1239}1240mi->dirty = true;1241}12421243void MeshStorage::mesh_instance_check_for_update(RID p_mesh_instance) {1244MeshInstance *mi = mesh_instance_owner.get_or_null(p_mesh_instance);12451246bool needs_update = mi->dirty;12471248if (mi->array_update_list.in_list()) {1249return;1250}12511252if (!needs_update && mi->skeleton.is_valid()) {1253Skeleton *sk = skeleton_owner.get_or_null(mi->skeleton);1254if (sk && sk->version != mi->skeleton_version) {1255needs_update = true;1256}1257}12581259if (needs_update) {1260dirty_mesh_instance_arrays.add(&mi->array_update_list);1261}1262}12631264void MeshStorage::mesh_instance_set_canvas_item_transform(RID p_mesh_instance, const Transform2D &p_transform) {1265MeshInstance *mi = mesh_instance_owner.get_or_null(p_mesh_instance);1266mi->canvas_item_transform_2d = p_transform;1267}12681269void MeshStorage::_blend_shape_bind_mesh_instance_buffer(MeshInstance *p_mi, uint32_t p_surface) {1270glBindBuffer(GL_ARRAY_BUFFER, p_mi->surfaces[p_surface].vertex_buffers[0]);12711272if ((p_mi->surfaces[p_surface].format_cache & (1ULL << RS::ARRAY_VERTEX))) {1273glEnableVertexAttribArray(RS::ARRAY_VERTEX);1274glVertexAttribPointer(RS::ARRAY_VERTEX, p_mi->surfaces[p_surface].vertex_size_cache, GL_FLOAT, GL_FALSE, p_mi->surfaces[p_surface].vertex_stride_cache, CAST_INT_TO_UCHAR_PTR(0));1275} else {1276glDisableVertexAttribArray(RS::ARRAY_VERTEX);1277}1278if ((p_mi->surfaces[p_surface].format_cache & (1ULL << RS::ARRAY_NORMAL))) {1279glEnableVertexAttribArray(RS::ARRAY_NORMAL);1280glVertexAttribIPointer(RS::ARRAY_NORMAL, 2, GL_UNSIGNED_INT, p_mi->surfaces[p_surface].vertex_stride_cache, CAST_INT_TO_UCHAR_PTR(p_mi->surfaces[p_surface].vertex_normal_offset_cache));1281} else {1282glDisableVertexAttribArray(RS::ARRAY_NORMAL);1283}1284if ((p_mi->surfaces[p_surface].format_cache & (1ULL << RS::ARRAY_TANGENT))) {1285glEnableVertexAttribArray(RS::ARRAY_TANGENT);1286glVertexAttribIPointer(RS::ARRAY_TANGENT, 2, GL_UNSIGNED_INT, p_mi->surfaces[p_surface].vertex_stride_cache, CAST_INT_TO_UCHAR_PTR(p_mi->surfaces[p_surface].vertex_tangent_offset_cache));1287} else {1288glDisableVertexAttribArray(RS::ARRAY_TANGENT);1289}1290}12911292void MeshStorage::_compute_skeleton(MeshInstance *p_mi, Skeleton *p_sk, uint32_t p_surface) {1293// Add in the bones and weights.1294glBindBuffer(GL_ARRAY_BUFFER, p_mi->mesh->surfaces[p_surface]->skin_buffer);12951296bool use_8_weights = p_mi->surfaces[p_surface].format_cache & RS::ARRAY_FLAG_USE_8_BONE_WEIGHTS;1297int skin_stride = sizeof(int16_t) * (use_8_weights ? 16 : 8);1298glEnableVertexAttribArray(RS::ARRAY_BONES);1299glVertexAttribIPointer(RS::ARRAY_BONES, 4, GL_UNSIGNED_SHORT, skin_stride, CAST_INT_TO_UCHAR_PTR(0));1300if (use_8_weights) {1301glEnableVertexAttribArray(11);1302glVertexAttribIPointer(11, 4, GL_UNSIGNED_SHORT, skin_stride, CAST_INT_TO_UCHAR_PTR(4 * sizeof(uint16_t)));1303glEnableVertexAttribArray(12);1304glVertexAttribPointer(12, 4, GL_UNSIGNED_SHORT, GL_TRUE, skin_stride, CAST_INT_TO_UCHAR_PTR(8 * sizeof(uint16_t)));1305glEnableVertexAttribArray(13);1306glVertexAttribPointer(13, 4, GL_UNSIGNED_SHORT, GL_TRUE, skin_stride, CAST_INT_TO_UCHAR_PTR(12 * sizeof(uint16_t)));1307} else {1308glEnableVertexAttribArray(RS::ARRAY_WEIGHTS);1309glVertexAttribPointer(RS::ARRAY_WEIGHTS, 4, GL_UNSIGNED_SHORT, GL_TRUE, skin_stride, CAST_INT_TO_UCHAR_PTR(4 * sizeof(uint16_t)));1310}13111312glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, p_mi->surfaces[p_surface].vertex_buffer);1313glActiveTexture(GL_TEXTURE0);1314glBindTexture(GL_TEXTURE_2D, p_sk->transforms_texture);13151316glBeginTransformFeedback(GL_POINTS);1317glDrawArrays(GL_POINTS, 0, p_mi->mesh->surfaces[p_surface]->vertex_count);1318glEndTransformFeedback();13191320glDisableVertexAttribArray(RS::ARRAY_BONES);1321glDisableVertexAttribArray(RS::ARRAY_WEIGHTS);1322glDisableVertexAttribArray(RS::ARRAY_BONES + 2);1323glDisableVertexAttribArray(RS::ARRAY_WEIGHTS + 2);1324glBindVertexArray(0);1325glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);1326}13271328void MeshStorage::update_mesh_instances() {1329if (dirty_mesh_instance_arrays.first() == nullptr) {1330return; //nothing to do1331}13321333glEnable(GL_RASTERIZER_DISCARD);1334glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);1335// Process skeletons and blend shapes using transform feedback1336while (dirty_mesh_instance_arrays.first()) {1337MeshInstance *mi = dirty_mesh_instance_arrays.first()->self();13381339Skeleton *sk = skeleton_owner.get_or_null(mi->skeleton);13401341// Precompute base weight if using blend shapes.1342float base_weight = 1.0;1343if (mi->surfaces.size() && mi->mesh->blend_shape_count && mi->mesh->blend_shape_mode == RS::BLEND_SHAPE_MODE_NORMALIZED) {1344for (uint32_t i = 0; i < mi->mesh->blend_shape_count; i++) {1345base_weight -= mi->blend_weights[i];1346}1347}13481349for (uint32_t i = 0; i < mi->surfaces.size(); i++) {1350if (mi->surfaces[i].vertex_buffer == 0) {1351continue;1352}13531354bool array_is_2d = mi->surfaces[i].format_cache & RS::ARRAY_FLAG_USE_2D_VERTICES;1355bool can_use_skeleton = sk != nullptr && sk->use_2d == array_is_2d && (mi->surfaces[i].format_cache & RS::ARRAY_FORMAT_BONES);1356bool use_8_weights = mi->surfaces[i].format_cache & RS::ARRAY_FLAG_USE_8_BONE_WEIGHTS;13571358// Always process blend shapes first.1359if (mi->mesh->blend_shape_count) {1360SkeletonShaderGLES3::ShaderVariant variant = SkeletonShaderGLES3::MODE_BASE_PASS;1361uint64_t specialization = 0;1362specialization |= array_is_2d ? SkeletonShaderGLES3::MODE_2D : 0;1363specialization |= SkeletonShaderGLES3::USE_BLEND_SHAPES;1364if (!array_is_2d) {1365if ((mi->surfaces[i].format_cache & (1ULL << RS::ARRAY_NORMAL))) {1366specialization |= SkeletonShaderGLES3::USE_NORMAL;1367}1368if ((mi->surfaces[i].format_cache & (1ULL << RS::ARRAY_TANGENT))) {1369specialization |= SkeletonShaderGLES3::USE_TANGENT;1370}1371}13721373bool success = skeleton_shader.shader.version_bind_shader(skeleton_shader.shader_version, variant, specialization);1374if (!success) {1375continue;1376}13771378skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::BLEND_WEIGHT, base_weight, skeleton_shader.shader_version, variant, specialization);1379skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::BLEND_SHAPE_COUNT, float(mi->mesh->blend_shape_count), skeleton_shader.shader_version, variant, specialization);13801381glBindBuffer(GL_ARRAY_BUFFER, 0);1382GLuint vertex_array_gl = 0;1383uint64_t mask = RS::ARRAY_FORMAT_VERTEX | RS::ARRAY_FORMAT_NORMAL | RS::ARRAY_FORMAT_VERTEX;1384uint64_t format = mi->mesh->surfaces[i]->format & mask; // Format should only have vertex, normal, tangent (as necessary).1385mesh_surface_get_vertex_arrays_and_format(mi->mesh->surfaces[i], format, vertex_array_gl);1386glBindVertexArray(vertex_array_gl);1387glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mi->surfaces[i].vertex_buffers[0]);1388glBeginTransformFeedback(GL_POINTS);1389glDrawArrays(GL_POINTS, 0, mi->mesh->surfaces[i]->vertex_count);1390glEndTransformFeedback();13911392variant = SkeletonShaderGLES3::MODE_BLEND_PASS;1393success = skeleton_shader.shader.version_bind_shader(skeleton_shader.shader_version, variant, specialization);1394if (!success) {1395continue;1396}13971398//Do the last blend shape separately, as it can be combined with the skeleton pass.1399for (uint32_t bs = 0; bs < mi->mesh->blend_shape_count - 1; bs++) {1400float weight = mi->blend_weights[bs];14011402if (Math::is_zero_approx(weight)) {1403//not bother with this one1404continue;1405}1406skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::BLEND_WEIGHT, weight, skeleton_shader.shader_version, variant, specialization);1407skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::BLEND_SHAPE_COUNT, float(mi->mesh->blend_shape_count), skeleton_shader.shader_version, variant, specialization);14081409glBindVertexArray(mi->mesh->surfaces[i]->blend_shapes[bs].vertex_array);1410_blend_shape_bind_mesh_instance_buffer(mi, i);1411glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mi->surfaces[i].vertex_buffers[1]);14121413glBeginTransformFeedback(GL_POINTS);1414glDrawArrays(GL_POINTS, 0, mi->mesh->surfaces[i]->vertex_count);1415glEndTransformFeedback();14161417SWAP(mi->surfaces[i].vertex_buffers[0], mi->surfaces[i].vertex_buffers[1]);1418}1419uint32_t bs = mi->mesh->blend_shape_count - 1;14201421float weight = mi->blend_weights[bs];14221423glBindVertexArray(mi->mesh->surfaces[i]->blend_shapes[bs].vertex_array);1424_blend_shape_bind_mesh_instance_buffer(mi, i);14251426specialization |= can_use_skeleton ? SkeletonShaderGLES3::USE_SKELETON : 0;1427specialization |= (can_use_skeleton && use_8_weights) ? SkeletonShaderGLES3::USE_EIGHT_WEIGHTS : 0;1428specialization |= SkeletonShaderGLES3::FINAL_PASS;1429success = skeleton_shader.shader.version_bind_shader(skeleton_shader.shader_version, variant, specialization);1430if (!success) {1431continue;1432}14331434skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::BLEND_WEIGHT, weight, skeleton_shader.shader_version, variant, specialization);1435skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::BLEND_SHAPE_COUNT, float(mi->mesh->blend_shape_count), skeleton_shader.shader_version, variant, specialization);14361437if (can_use_skeleton) {1438Transform2D transform = mi->canvas_item_transform_2d.affine_inverse() * sk->base_transform_2d;1439skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::SKELETON_TRANSFORM_X, transform[0], skeleton_shader.shader_version, variant, specialization);1440skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::SKELETON_TRANSFORM_Y, transform[1], skeleton_shader.shader_version, variant, specialization);1441skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::SKELETON_TRANSFORM_OFFSET, transform[2], skeleton_shader.shader_version, variant, specialization);14421443Transform2D inverse_transform = transform.affine_inverse();1444skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_X, inverse_transform[0], skeleton_shader.shader_version, variant, specialization);1445skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_Y, inverse_transform[1], skeleton_shader.shader_version, variant, specialization);1446skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_OFFSET, inverse_transform[2], skeleton_shader.shader_version, variant, specialization);14471448// Do last blendshape in the same pass as the Skeleton.1449_compute_skeleton(mi, sk, i);1450can_use_skeleton = false;1451} else {1452// Do last blendshape by itself and prepare vertex data for use by the renderer.1453glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mi->surfaces[i].vertex_buffer);14541455glBeginTransformFeedback(GL_POINTS);1456glDrawArrays(GL_POINTS, 0, mi->mesh->surfaces[i]->vertex_count);1457glEndTransformFeedback();1458}14591460glBindVertexArray(0);1461glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);1462}14631464// This branch should only execute when Skeleton is run by itself.1465if (can_use_skeleton) {1466SkeletonShaderGLES3::ShaderVariant variant = SkeletonShaderGLES3::MODE_BASE_PASS;1467uint64_t specialization = 0;1468specialization |= array_is_2d ? SkeletonShaderGLES3::MODE_2D : 0;1469specialization |= SkeletonShaderGLES3::USE_SKELETON;1470specialization |= SkeletonShaderGLES3::FINAL_PASS;1471specialization |= use_8_weights ? SkeletonShaderGLES3::USE_EIGHT_WEIGHTS : 0;1472if (!array_is_2d) {1473if ((mi->surfaces[i].format_cache & (1ULL << RS::ARRAY_NORMAL))) {1474specialization |= SkeletonShaderGLES3::USE_NORMAL;1475}1476if ((mi->surfaces[i].format_cache & (1ULL << RS::ARRAY_TANGENT))) {1477specialization |= SkeletonShaderGLES3::USE_TANGENT;1478}1479}14801481bool success = skeleton_shader.shader.version_bind_shader(skeleton_shader.shader_version, variant, specialization);1482if (!success) {1483continue;1484}14851486Transform2D transform = mi->canvas_item_transform_2d.affine_inverse() * sk->base_transform_2d;1487skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::SKELETON_TRANSFORM_X, transform[0], skeleton_shader.shader_version, variant, specialization);1488skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::SKELETON_TRANSFORM_Y, transform[1], skeleton_shader.shader_version, variant, specialization);1489skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::SKELETON_TRANSFORM_OFFSET, transform[2], skeleton_shader.shader_version, variant, specialization);14901491Transform2D inverse_transform = transform.affine_inverse();1492skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_X, inverse_transform[0], skeleton_shader.shader_version, variant, specialization);1493skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_Y, inverse_transform[1], skeleton_shader.shader_version, variant, specialization);1494skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_OFFSET, inverse_transform[2], skeleton_shader.shader_version, variant, specialization);14951496GLuint vertex_array_gl = 0;1497uint64_t mask = RS::ARRAY_FORMAT_VERTEX | RS::ARRAY_FORMAT_NORMAL | RS::ARRAY_FORMAT_VERTEX;1498uint64_t format = mi->mesh->surfaces[i]->format & mask; // Format should only have vertex, normal, tangent (as necessary).1499mesh_surface_get_vertex_arrays_and_format(mi->mesh->surfaces[i], format, vertex_array_gl);1500glBindVertexArray(vertex_array_gl);1501_compute_skeleton(mi, sk, i);1502}1503}1504mi->dirty = false;1505if (sk) {1506mi->skeleton_version = sk->version;1507}1508dirty_mesh_instance_arrays.remove(&mi->array_update_list);1509}1510glDisable(GL_RASTERIZER_DISCARD);1511glBindBuffer(GL_ARRAY_BUFFER, 0);1512glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);1513}15141515/* MULTIMESH API */15161517RID MeshStorage::_multimesh_allocate() {1518return multimesh_owner.allocate_rid();1519}15201521void MeshStorage::_multimesh_initialize(RID p_rid) {1522multimesh_owner.initialize_rid(p_rid, MultiMesh());1523}15241525void MeshStorage::_multimesh_free(RID p_rid) {1526// Remove from interpolator.1527_interpolation_data.notify_free_multimesh(p_rid);1528_update_dirty_multimeshes();1529multimesh_allocate_data(p_rid, 0, RS::MULTIMESH_TRANSFORM_2D);1530MultiMesh *multimesh = multimesh_owner.get_or_null(p_rid);1531multimesh->dependency.deleted_notify(p_rid);1532multimesh_owner.free(p_rid);1533}15341535void MeshStorage::_multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data, bool p_use_indirect) {1536MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1537ERR_FAIL_NULL(multimesh);15381539if (multimesh->instances == p_instances && multimesh->xform_format == p_transform_format && multimesh->uses_colors == p_use_colors && multimesh->uses_custom_data == p_use_custom_data) {1540return;1541}15421543if (multimesh->buffer) {1544GLES3::Utilities::get_singleton()->buffer_free_data(multimesh->buffer);1545multimesh->buffer = 0;1546}15471548if (multimesh->data_cache_dirty_regions) {1549memdelete_arr(multimesh->data_cache_dirty_regions);1550multimesh->data_cache_dirty_regions = nullptr;1551multimesh->data_cache_used_dirty_regions = 0;1552}15531554// If we have either color or custom data, reserve space for both to make data handling logic simpler.1555// This way we can always treat them both as a single, compressed uvec4.1556int color_and_custom_strides = (p_use_colors || p_use_custom_data) ? 2 : 0;15571558multimesh->instances = p_instances;1559multimesh->xform_format = p_transform_format;1560multimesh->uses_colors = p_use_colors;1561multimesh->color_offset_cache = p_transform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12;1562multimesh->uses_custom_data = p_use_custom_data;1563multimesh->custom_data_offset_cache = multimesh->color_offset_cache + color_and_custom_strides;1564multimesh->stride_cache = multimesh->custom_data_offset_cache + color_and_custom_strides;1565multimesh->buffer_set = false;15661567multimesh->data_cache = Vector<float>();1568multimesh->aabb = AABB();1569multimesh->aabb_dirty = false;1570multimesh->visible_instances = MIN(multimesh->visible_instances, multimesh->instances);15711572if (multimesh->instances) {1573glGenBuffers(1, &multimesh->buffer);1574glBindBuffer(GL_ARRAY_BUFFER, multimesh->buffer);1575GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, multimesh->buffer, multimesh->instances * multimesh->stride_cache * sizeof(float), nullptr, GL_STATIC_DRAW, "MultiMesh buffer");1576glBindBuffer(GL_ARRAY_BUFFER, 0);1577}15781579multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MULTIMESH);1580}15811582int MeshStorage::_multimesh_get_instance_count(RID p_multimesh) const {1583MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1584ERR_FAIL_NULL_V(multimesh, 0);1585return multimesh->instances;1586}15871588void MeshStorage::_multimesh_set_mesh(RID p_multimesh, RID p_mesh) {1589MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1590ERR_FAIL_NULL(multimesh);1591if (multimesh->mesh == p_mesh || p_mesh.is_null()) {1592return;1593}1594multimesh->mesh = p_mesh;15951596if (multimesh->instances == 0) {1597return;1598}15991600if (multimesh->data_cache.size()) {1601//we have a data cache, just mark it dirty1602_multimesh_mark_all_dirty(multimesh, false, true);1603} else if (multimesh->instances) {1604// Need to re-create AABB. Unfortunately, calling this has a penalty.1605if (multimesh->buffer_set) {1606Vector<uint8_t> buffer = Utilities::buffer_get_data(GL_ARRAY_BUFFER, multimesh->buffer, multimesh->instances * multimesh->stride_cache * sizeof(float));1607const uint8_t *r = buffer.ptr();1608const float *data = (const float *)r;1609_multimesh_re_create_aabb(multimesh, data, multimesh->instances);1610}1611}16121613multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);1614}16151616#define MULTIMESH_DIRTY_REGION_SIZE 51216171618void MeshStorage::_multimesh_make_local(MultiMesh *multimesh) const {1619if (multimesh->data_cache.size() > 0 || multimesh->instances == 0) {1620return; //already local1621}1622ERR_FAIL_COND(multimesh->data_cache.size() > 0);1623// this means that the user wants to load/save individual elements,1624// for this, the data must reside on CPU, so just copy it there.1625multimesh->data_cache.resize(multimesh->instances * multimesh->stride_cache);1626{1627float *w = multimesh->data_cache.ptrw();16281629if (multimesh->buffer_set) {1630Vector<uint8_t> buffer = Utilities::buffer_get_data(GL_ARRAY_BUFFER, multimesh->buffer, multimesh->instances * multimesh->stride_cache * sizeof(float));16311632{1633const uint8_t *r = buffer.ptr();1634memcpy(w, r, buffer.size());1635}1636} else {1637memset(w, 0, (size_t)multimesh->instances * multimesh->stride_cache * sizeof(float));1638}1639}1640uint32_t data_cache_dirty_region_count = Math::division_round_up(multimesh->instances, MULTIMESH_DIRTY_REGION_SIZE);1641multimesh->data_cache_dirty_regions = memnew_arr(bool, data_cache_dirty_region_count);1642for (uint32_t i = 0; i < data_cache_dirty_region_count; i++) {1643multimesh->data_cache_dirty_regions[i] = false;1644}1645multimesh->data_cache_used_dirty_regions = 0;1646}16471648void MeshStorage::_multimesh_mark_dirty(MultiMesh *multimesh, int p_index, bool p_aabb) {1649uint32_t region_index = p_index / MULTIMESH_DIRTY_REGION_SIZE;1650#ifdef DEBUG_ENABLED1651uint32_t data_cache_dirty_region_count = Math::division_round_up(multimesh->instances, MULTIMESH_DIRTY_REGION_SIZE);1652ERR_FAIL_UNSIGNED_INDEX(region_index, data_cache_dirty_region_count); //bug1653#endif1654if (!multimesh->data_cache_dirty_regions[region_index]) {1655multimesh->data_cache_dirty_regions[region_index] = true;1656multimesh->data_cache_used_dirty_regions++;1657}16581659if (p_aabb) {1660multimesh->aabb_dirty = true;1661}16621663if (!multimesh->dirty) {1664multimesh->dirty_list = multimesh_dirty_list;1665multimesh_dirty_list = multimesh;1666multimesh->dirty = true;1667}1668}16691670void MeshStorage::_multimesh_mark_all_dirty(MultiMesh *multimesh, bool p_data, bool p_aabb) {1671if (p_data) {1672uint32_t data_cache_dirty_region_count = Math::division_round_up(multimesh->instances, MULTIMESH_DIRTY_REGION_SIZE);16731674for (uint32_t i = 0; i < data_cache_dirty_region_count; i++) {1675if (!multimesh->data_cache_dirty_regions[i]) {1676multimesh->data_cache_dirty_regions[i] = true;1677multimesh->data_cache_used_dirty_regions++;1678}1679}1680}16811682if (p_aabb) {1683multimesh->aabb_dirty = true;1684}16851686if (!multimesh->dirty) {1687multimesh->dirty_list = multimesh_dirty_list;1688multimesh_dirty_list = multimesh;1689multimesh->dirty = true;1690}1691}16921693void MeshStorage::_multimesh_re_create_aabb(MultiMesh *multimesh, const float *p_data, int p_instances) {1694ERR_FAIL_COND(multimesh->mesh.is_null());1695if (multimesh->custom_aabb != AABB()) {1696return;1697}1698AABB aabb;1699AABB mesh_aabb = mesh_get_aabb(multimesh->mesh);1700for (int i = 0; i < p_instances; i++) {1701const float *data = p_data + multimesh->stride_cache * i;1702Transform3D t;17031704if (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_3D) {1705t.basis.rows[0][0] = data[0];1706t.basis.rows[0][1] = data[1];1707t.basis.rows[0][2] = data[2];1708t.origin.x = data[3];1709t.basis.rows[1][0] = data[4];1710t.basis.rows[1][1] = data[5];1711t.basis.rows[1][2] = data[6];1712t.origin.y = data[7];1713t.basis.rows[2][0] = data[8];1714t.basis.rows[2][1] = data[9];1715t.basis.rows[2][2] = data[10];1716t.origin.z = data[11];17171718} else {1719t.basis.rows[0][0] = data[0];1720t.basis.rows[0][1] = data[1];1721t.origin.x = data[3];17221723t.basis.rows[1][0] = data[4];1724t.basis.rows[1][1] = data[5];1725t.origin.y = data[7];1726}17271728if (i == 0) {1729aabb = t.xform(mesh_aabb);1730} else {1731aabb.merge_with(t.xform(mesh_aabb));1732}1733}17341735multimesh->aabb = aabb;1736}17371738void MeshStorage::_multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform3D &p_transform) {1739MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1740ERR_FAIL_NULL(multimesh);1741ERR_FAIL_INDEX(p_index, multimesh->instances);1742ERR_FAIL_COND(multimesh->xform_format != RS::MULTIMESH_TRANSFORM_3D);17431744_multimesh_make_local(multimesh);17451746{1747float *w = multimesh->data_cache.ptrw();17481749float *dataptr = w + p_index * multimesh->stride_cache;17501751dataptr[0] = p_transform.basis.rows[0][0];1752dataptr[1] = p_transform.basis.rows[0][1];1753dataptr[2] = p_transform.basis.rows[0][2];1754dataptr[3] = p_transform.origin.x;1755dataptr[4] = p_transform.basis.rows[1][0];1756dataptr[5] = p_transform.basis.rows[1][1];1757dataptr[6] = p_transform.basis.rows[1][2];1758dataptr[7] = p_transform.origin.y;1759dataptr[8] = p_transform.basis.rows[2][0];1760dataptr[9] = p_transform.basis.rows[2][1];1761dataptr[10] = p_transform.basis.rows[2][2];1762dataptr[11] = p_transform.origin.z;1763}17641765_multimesh_mark_dirty(multimesh, p_index, true);1766}17671768void MeshStorage::_multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) {1769MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1770ERR_FAIL_NULL(multimesh);1771ERR_FAIL_INDEX(p_index, multimesh->instances);1772ERR_FAIL_COND(multimesh->xform_format != RS::MULTIMESH_TRANSFORM_2D);17731774_multimesh_make_local(multimesh);17751776{1777float *w = multimesh->data_cache.ptrw();17781779float *dataptr = w + p_index * multimesh->stride_cache;17801781dataptr[0] = p_transform.columns[0][0];1782dataptr[1] = p_transform.columns[1][0];1783dataptr[2] = 0;1784dataptr[3] = p_transform.columns[2][0];1785dataptr[4] = p_transform.columns[0][1];1786dataptr[5] = p_transform.columns[1][1];1787dataptr[6] = 0;1788dataptr[7] = p_transform.columns[2][1];1789}17901791_multimesh_mark_dirty(multimesh, p_index, true);1792}17931794void MeshStorage::_multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) {1795MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1796ERR_FAIL_NULL(multimesh);1797ERR_FAIL_INDEX(p_index, multimesh->instances);1798ERR_FAIL_COND(!multimesh->uses_colors);17991800_multimesh_make_local(multimesh);18011802{1803// Colors are packed into 2 floats.1804float *w = multimesh->data_cache.ptrw();18051806float *dataptr = w + p_index * multimesh->stride_cache + multimesh->color_offset_cache;1807uint16_t val[4] = { Math::make_half_float(p_color.r), Math::make_half_float(p_color.g), Math::make_half_float(p_color.b), Math::make_half_float(p_color.a) };1808memcpy(dataptr, val, 2 * 4);1809}18101811_multimesh_mark_dirty(multimesh, p_index, false);1812}18131814void MeshStorage::_multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) {1815MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1816ERR_FAIL_NULL(multimesh);1817ERR_FAIL_INDEX(p_index, multimesh->instances);1818ERR_FAIL_COND(!multimesh->uses_custom_data);18191820_multimesh_make_local(multimesh);18211822{1823float *w = multimesh->data_cache.ptrw();18241825float *dataptr = w + p_index * multimesh->stride_cache + multimesh->custom_data_offset_cache;1826uint16_t val[4] = { Math::make_half_float(p_color.r), Math::make_half_float(p_color.g), Math::make_half_float(p_color.b), Math::make_half_float(p_color.a) };1827memcpy(dataptr, val, 2 * 4);1828}18291830_multimesh_mark_dirty(multimesh, p_index, false);1831}18321833RID MeshStorage::_multimesh_get_mesh(RID p_multimesh) const {1834MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1835ERR_FAIL_NULL_V(multimesh, RID());18361837return multimesh->mesh;1838}18391840void MeshStorage::_multimesh_set_custom_aabb(RID p_multimesh, const AABB &p_aabb) {1841MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1842ERR_FAIL_NULL(multimesh);1843multimesh->custom_aabb = p_aabb;1844multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);1845}18461847AABB MeshStorage::_multimesh_get_custom_aabb(RID p_multimesh) const {1848MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1849ERR_FAIL_NULL_V(multimesh, AABB());1850return multimesh->custom_aabb;1851}18521853AABB MeshStorage::_multimesh_get_aabb(RID p_multimesh) {1854MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1855ERR_FAIL_NULL_V(multimesh, AABB());1856if (multimesh->custom_aabb != AABB()) {1857return multimesh->custom_aabb;1858}1859if (multimesh->aabb_dirty) {1860_update_dirty_multimeshes();1861}1862return multimesh->aabb;1863}18641865Transform3D MeshStorage::_multimesh_instance_get_transform(RID p_multimesh, int p_index) const {1866MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1867ERR_FAIL_NULL_V(multimesh, Transform3D());1868ERR_FAIL_INDEX_V(p_index, multimesh->instances, Transform3D());1869ERR_FAIL_COND_V(multimesh->xform_format != RS::MULTIMESH_TRANSFORM_3D, Transform3D());18701871_multimesh_make_local(multimesh);18721873Transform3D t;1874{1875const float *r = multimesh->data_cache.ptr();18761877const float *dataptr = r + p_index * multimesh->stride_cache;18781879t.basis.rows[0][0] = dataptr[0];1880t.basis.rows[0][1] = dataptr[1];1881t.basis.rows[0][2] = dataptr[2];1882t.origin.x = dataptr[3];1883t.basis.rows[1][0] = dataptr[4];1884t.basis.rows[1][1] = dataptr[5];1885t.basis.rows[1][2] = dataptr[6];1886t.origin.y = dataptr[7];1887t.basis.rows[2][0] = dataptr[8];1888t.basis.rows[2][1] = dataptr[9];1889t.basis.rows[2][2] = dataptr[10];1890t.origin.z = dataptr[11];1891}18921893return t;1894}18951896Transform2D MeshStorage::_multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const {1897MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1898ERR_FAIL_NULL_V(multimesh, Transform2D());1899ERR_FAIL_INDEX_V(p_index, multimesh->instances, Transform2D());1900ERR_FAIL_COND_V(multimesh->xform_format != RS::MULTIMESH_TRANSFORM_2D, Transform2D());19011902_multimesh_make_local(multimesh);19031904Transform2D t;1905{1906const float *r = multimesh->data_cache.ptr();19071908const float *dataptr = r + p_index * multimesh->stride_cache;19091910t.columns[0][0] = dataptr[0];1911t.columns[1][0] = dataptr[1];1912t.columns[2][0] = dataptr[3];1913t.columns[0][1] = dataptr[4];1914t.columns[1][1] = dataptr[5];1915t.columns[2][1] = dataptr[7];1916}19171918return t;1919}19201921Color MeshStorage::_multimesh_instance_get_color(RID p_multimesh, int p_index) const {1922MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1923ERR_FAIL_NULL_V(multimesh, Color());1924ERR_FAIL_INDEX_V(p_index, multimesh->instances, Color());1925ERR_FAIL_COND_V(!multimesh->uses_colors, Color());19261927_multimesh_make_local(multimesh);19281929Color c;1930{1931const float *r = multimesh->data_cache.ptr();19321933const float *dataptr = r + p_index * multimesh->stride_cache + multimesh->color_offset_cache;1934uint16_t raw_data[4];1935memcpy(raw_data, dataptr, 2 * 4);1936c.r = Math::half_to_float(raw_data[0]);1937c.g = Math::half_to_float(raw_data[1]);1938c.b = Math::half_to_float(raw_data[2]);1939c.a = Math::half_to_float(raw_data[3]);1940}19411942return c;1943}19441945Color MeshStorage::_multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const {1946MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1947ERR_FAIL_NULL_V(multimesh, Color());1948ERR_FAIL_INDEX_V(p_index, multimesh->instances, Color());1949ERR_FAIL_COND_V(!multimesh->uses_custom_data, Color());19501951_multimesh_make_local(multimesh);19521953Color c;1954{1955const float *r = multimesh->data_cache.ptr();19561957const float *dataptr = r + p_index * multimesh->stride_cache + multimesh->custom_data_offset_cache;1958uint16_t raw_data[4];1959memcpy(raw_data, dataptr, 2 * 4);1960c.r = Math::half_to_float(raw_data[0]);1961c.g = Math::half_to_float(raw_data[1]);1962c.b = Math::half_to_float(raw_data[2]);1963c.a = Math::half_to_float(raw_data[3]);1964}19651966return c;1967}19681969void MeshStorage::_multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_buffer) {1970MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1971ERR_FAIL_NULL(multimesh);19721973if (multimesh->uses_colors || multimesh->uses_custom_data) {1974// Color and custom need to be packed so copy buffer to data_cache and pack.19751976_multimesh_make_local(multimesh);19771978uint32_t old_stride = multimesh->xform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12;1979old_stride += multimesh->uses_colors ? 4 : 0;1980old_stride += multimesh->uses_custom_data ? 4 : 0;1981ERR_FAIL_COND(p_buffer.size() != (multimesh->instances * (int)old_stride));19821983multimesh->data_cache = p_buffer;19841985float *w = multimesh->data_cache.ptrw();19861987for (int i = 0; i < multimesh->instances; i++) {1988{1989float *dataptr = w + i * old_stride;1990float *newptr = w + i * multimesh->stride_cache;1991float vals[8] = { dataptr[0], dataptr[1], dataptr[2], dataptr[3], dataptr[4], dataptr[5], dataptr[6], dataptr[7] };1992memcpy(newptr, vals, 8 * 4);1993}19941995if (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_3D) {1996float *dataptr = w + i * old_stride + 8;1997float *newptr = w + i * multimesh->stride_cache + 8;1998float vals[8] = { dataptr[0], dataptr[1], dataptr[2], dataptr[3] };1999memcpy(newptr, vals, 4 * 4);2000}20012002if (multimesh->uses_colors) {2003float *dataptr = w + i * old_stride + (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12);2004float *newptr = w + i * multimesh->stride_cache + multimesh->color_offset_cache;2005uint16_t val[4] = { Math::make_half_float(dataptr[0]), Math::make_half_float(dataptr[1]), Math::make_half_float(dataptr[2]), Math::make_half_float(dataptr[3]) };2006memcpy(newptr, val, 2 * 4);2007}2008if (multimesh->uses_custom_data) {2009float *dataptr = w + i * old_stride + (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12) + (multimesh->uses_colors ? 4 : 0);2010float *newptr = w + i * multimesh->stride_cache + multimesh->custom_data_offset_cache;2011uint16_t val[4] = { Math::make_half_float(dataptr[0]), Math::make_half_float(dataptr[1]), Math::make_half_float(dataptr[2]), Math::make_half_float(dataptr[3]) };2012memcpy(newptr, val, 2 * 4);2013}2014}20152016multimesh->data_cache.resize(multimesh->instances * (int)multimesh->stride_cache);2017const float *r = multimesh->data_cache.ptr();2018glBindBuffer(GL_ARRAY_BUFFER, multimesh->buffer);2019glBufferData(GL_ARRAY_BUFFER, multimesh->data_cache.size() * sizeof(float), r, GL_STATIC_DRAW);2020glBindBuffer(GL_ARRAY_BUFFER, 0);20212022} else {2023// If we have a data cache, just update it.2024if (multimesh->data_cache.size()) {2025multimesh->data_cache = p_buffer;2026}20272028// Only Transform is being used, so we can upload directly.2029ERR_FAIL_COND(p_buffer.size() != (multimesh->instances * (int)multimesh->stride_cache));2030const float *r = p_buffer.ptr();2031glBindBuffer(GL_ARRAY_BUFFER, multimesh->buffer);2032glBufferData(GL_ARRAY_BUFFER, p_buffer.size() * sizeof(float), r, GL_STATIC_DRAW);2033glBindBuffer(GL_ARRAY_BUFFER, 0);2034}20352036multimesh->buffer_set = true;20372038if (multimesh->data_cache.size() || multimesh->uses_colors || multimesh->uses_custom_data) {2039// Clear dirty since nothing will be dirty anymore.2040uint32_t data_cache_dirty_region_count = Math::division_round_up(multimesh->instances, MULTIMESH_DIRTY_REGION_SIZE);2041for (uint32_t i = 0; i < data_cache_dirty_region_count; i++) {2042multimesh->data_cache_dirty_regions[i] = false;2043}2044multimesh->data_cache_used_dirty_regions = 0;20452046_multimesh_mark_all_dirty(multimesh, false, true); //update AABB2047} else if (multimesh->mesh.is_valid()) {2048//if we have a mesh set, we need to re-generate the AABB from the new data2049const float *data = p_buffer.ptr();20502051if (multimesh->custom_aabb == AABB()) {2052_multimesh_re_create_aabb(multimesh, data, multimesh->instances);2053multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);2054}2055}2056}20572058RID MeshStorage::_multimesh_get_command_buffer_rd_rid(RID p_multimesh) const {2059ERR_FAIL_V_MSG(RID(), "GLES3 does not implement indirect multimeshes.");2060}20612062RID MeshStorage::_multimesh_get_buffer_rd_rid(RID p_multimesh) const {2063ERR_FAIL_V_MSG(RID(), "GLES3 does not contain a Rid for the multimesh buffer.");2064}20652066Vector<float> MeshStorage::_multimesh_get_buffer(RID p_multimesh) const {2067MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);2068ERR_FAIL_NULL_V(multimesh, Vector<float>());2069Vector<float> ret;2070if (multimesh->buffer == 0 || multimesh->instances == 0) {2071return Vector<float>();2072} else if (multimesh->data_cache.size()) {2073ret = multimesh->data_cache;2074} else {2075// Buffer not cached, so fetch from GPU memory. This can be a stalling operation, avoid whenever possible.20762077Vector<uint8_t> buffer = Utilities::buffer_get_data(GL_ARRAY_BUFFER, multimesh->buffer, multimesh->instances * multimesh->stride_cache * sizeof(float));2078ret.resize(multimesh->instances * multimesh->stride_cache);2079{2080float *w = ret.ptrw();2081const uint8_t *r = buffer.ptr();2082memcpy(w, r, buffer.size());2083}2084}2085if (multimesh->uses_colors || multimesh->uses_custom_data) {2086// Need to decompress buffer.2087uint32_t new_stride = multimesh->xform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12;2088new_stride += multimesh->uses_colors ? 4 : 0;2089new_stride += multimesh->uses_custom_data ? 4 : 0;20902091Vector<float> decompressed;2092decompressed.resize(multimesh->instances * (int)new_stride);2093float *w = decompressed.ptrw();2094const float *r = ret.ptr();20952096for (int i = 0; i < multimesh->instances; i++) {2097{2098float *newptr = w + i * new_stride;2099const float *oldptr = r + i * multimesh->stride_cache;2100float vals[8] = { oldptr[0], oldptr[1], oldptr[2], oldptr[3], oldptr[4], oldptr[5], oldptr[6], oldptr[7] };2101memcpy(newptr, vals, 8 * 4);2102}21032104if (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_3D) {2105float *newptr = w + i * new_stride + 8;2106const float *oldptr = r + i * multimesh->stride_cache + 8;2107float vals[8] = { oldptr[0], oldptr[1], oldptr[2], oldptr[3] };2108memcpy(newptr, vals, 4 * 4);2109}21102111if (multimesh->uses_colors) {2112float *newptr = w + i * new_stride + (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12);2113const float *oldptr = r + i * multimesh->stride_cache + multimesh->color_offset_cache;2114uint16_t raw_data[4];2115memcpy(raw_data, oldptr, 2 * 4);2116newptr[0] = Math::half_to_float(raw_data[0]);2117newptr[1] = Math::half_to_float(raw_data[1]);2118newptr[2] = Math::half_to_float(raw_data[2]);2119newptr[3] = Math::half_to_float(raw_data[3]);2120}2121if (multimesh->uses_custom_data) {2122float *newptr = w + i * new_stride + (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12) + (multimesh->uses_colors ? 4 : 0);2123const float *oldptr = r + i * multimesh->stride_cache + multimesh->custom_data_offset_cache;2124uint16_t raw_data[4];2125memcpy(raw_data, oldptr, 2 * 4);2126newptr[0] = Math::half_to_float(raw_data[0]);2127newptr[1] = Math::half_to_float(raw_data[1]);2128newptr[2] = Math::half_to_float(raw_data[2]);2129newptr[3] = Math::half_to_float(raw_data[3]);2130}2131}2132return decompressed;2133} else {2134return ret;2135}2136}21372138void MeshStorage::_multimesh_set_visible_instances(RID p_multimesh, int p_visible) {2139MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);2140ERR_FAIL_NULL(multimesh);2141ERR_FAIL_COND(p_visible < -1 || p_visible > multimesh->instances);2142if (multimesh->visible_instances == p_visible) {2143return;2144}21452146if (multimesh->data_cache.size()) {2147// There is a data cache, but we may need to update some sections.2148_multimesh_mark_all_dirty(multimesh, false, true);2149int start = multimesh->visible_instances >= 0 ? multimesh->visible_instances : multimesh->instances;2150for (int i = start; i < p_visible; i++) {2151_multimesh_mark_dirty(multimesh, i, true);2152}2153}21542155multimesh->visible_instances = p_visible;21562157multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES);2158}21592160int MeshStorage::_multimesh_get_visible_instances(RID p_multimesh) const {2161MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);2162ERR_FAIL_NULL_V(multimesh, 0);2163return multimesh->visible_instances;2164}21652166MeshStorage::MultiMeshInterpolator *MeshStorage::_multimesh_get_interpolator(RID p_multimesh) const {2167MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);2168ERR_FAIL_NULL_V_MSG(multimesh, nullptr, "Multimesh not found: " + itos(p_multimesh.get_id()));21692170return &multimesh->interpolator;2171}21722173void MeshStorage::_update_dirty_multimeshes() {2174while (multimesh_dirty_list) {2175MultiMesh *multimesh = multimesh_dirty_list;21762177if (multimesh->data_cache.size()) { //may have been cleared, so only process if it exists2178const float *data = multimesh->data_cache.ptr();21792180uint32_t visible_instances = multimesh->visible_instances >= 0 ? multimesh->visible_instances : multimesh->instances;21812182if (multimesh->data_cache_used_dirty_regions) {2183uint32_t data_cache_dirty_region_count = Math::division_round_up(multimesh->instances, (int)MULTIMESH_DIRTY_REGION_SIZE);2184uint32_t visible_region_count = visible_instances == 0 ? 0 : Math::division_round_up(visible_instances, (uint32_t)MULTIMESH_DIRTY_REGION_SIZE);21852186GLint region_size = multimesh->stride_cache * MULTIMESH_DIRTY_REGION_SIZE * sizeof(float);21872188if (multimesh->data_cache_used_dirty_regions > 32 || multimesh->data_cache_used_dirty_regions > visible_region_count / 2) {2189// If there too many dirty regions, or represent the majority of regions, just copy all, else transfer cost piles up too much2190glBindBuffer(GL_ARRAY_BUFFER, multimesh->buffer);2191glBufferSubData(GL_ARRAY_BUFFER, 0, MIN(visible_region_count * region_size, multimesh->instances * multimesh->stride_cache * sizeof(float)), data);2192glBindBuffer(GL_ARRAY_BUFFER, 0);2193} else {2194// Not that many regions? update them all2195// TODO: profile the performance cost on low end2196glBindBuffer(GL_ARRAY_BUFFER, multimesh->buffer);2197for (uint32_t i = 0; i < visible_region_count; i++) {2198if (multimesh->data_cache_dirty_regions[i]) {2199GLint offset = i * region_size;2200GLint size = multimesh->stride_cache * (uint32_t)multimesh->instances * (uint32_t)sizeof(float);2201uint32_t region_start_index = multimesh->stride_cache * MULTIMESH_DIRTY_REGION_SIZE * i;2202glBufferSubData(GL_ARRAY_BUFFER, offset, MIN(region_size, size - offset), &data[region_start_index]);2203}2204}2205glBindBuffer(GL_ARRAY_BUFFER, 0);2206}22072208for (uint32_t i = 0; i < data_cache_dirty_region_count; i++) {2209multimesh->data_cache_dirty_regions[i] = false;2210}22112212multimesh->data_cache_used_dirty_regions = 0;2213}22142215if (multimesh->aabb_dirty && multimesh->mesh.is_valid()) {2216multimesh->aabb_dirty = false;2217if (multimesh->custom_aabb == AABB()) {2218_multimesh_re_create_aabb(multimesh, data, visible_instances);2219multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);2220}2221}2222}22232224multimesh_dirty_list = multimesh->dirty_list;22252226multimesh->dirty_list = nullptr;2227multimesh->dirty = false;2228}22292230multimesh_dirty_list = nullptr;2231}22322233/* SKELETON API */22342235RID MeshStorage::skeleton_allocate() {2236return skeleton_owner.allocate_rid();2237}22382239void MeshStorage::skeleton_initialize(RID p_rid) {2240skeleton_owner.initialize_rid(p_rid, Skeleton());2241}22422243void MeshStorage::skeleton_free(RID p_rid) {2244_update_dirty_skeletons();2245skeleton_allocate_data(p_rid, 0);2246Skeleton *skeleton = skeleton_owner.get_or_null(p_rid);2247skeleton->dependency.deleted_notify(p_rid);2248skeleton_owner.free(p_rid);2249}22502251void MeshStorage::_skeleton_make_dirty(Skeleton *skeleton) {2252if (!skeleton->dirty) {2253skeleton->dirty = true;2254skeleton->dirty_list = skeleton_dirty_list;2255skeleton_dirty_list = skeleton;2256}2257}22582259void MeshStorage::skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton) {2260Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);2261ERR_FAIL_NULL(skeleton);2262ERR_FAIL_COND(p_bones < 0);22632264if (skeleton->size == p_bones && skeleton->use_2d == p_2d_skeleton) {2265return;2266}22672268skeleton->size = p_bones;2269skeleton->use_2d = p_2d_skeleton;2270skeleton->height = (p_bones * (p_2d_skeleton ? 2 : 3)) / 256;2271if ((p_bones * (p_2d_skeleton ? 2 : 3)) % 256) {2272skeleton->height++;2273}22742275if (skeleton->transforms_texture != 0) {2276GLES3::Utilities::get_singleton()->texture_free_data(skeleton->transforms_texture);2277skeleton->transforms_texture = 0;2278skeleton->data.clear();2279}22802281if (skeleton->size) {2282skeleton->data.resize(256 * skeleton->height * 4);2283glGenTextures(1, &skeleton->transforms_texture);2284glBindTexture(GL_TEXTURE_2D, skeleton->transforms_texture);2285glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 256, skeleton->height, 0, GL_RGBA, GL_FLOAT, nullptr);2286glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);2287glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);2288glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);2289glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);2290glBindTexture(GL_TEXTURE_2D, 0);2291GLES3::Utilities::get_singleton()->texture_allocated_data(skeleton->transforms_texture, skeleton->data.size() * sizeof(float), "Skeleton transforms texture");22922293memset(skeleton->data.ptr(), 0, skeleton->data.size() * sizeof(float));22942295_skeleton_make_dirty(skeleton);2296}22972298skeleton->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_SKELETON_DATA);2299}23002301void MeshStorage::skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) {2302Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);23032304ERR_FAIL_NULL(skeleton);2305ERR_FAIL_COND(!skeleton->use_2d);23062307skeleton->base_transform_2d = p_base_transform;2308}23092310int MeshStorage::skeleton_get_bone_count(RID p_skeleton) const {2311Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);2312ERR_FAIL_NULL_V(skeleton, 0);23132314return skeleton->size;2315}23162317void MeshStorage::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform3D &p_transform) {2318Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);23192320ERR_FAIL_NULL(skeleton);2321ERR_FAIL_INDEX(p_bone, skeleton->size);2322ERR_FAIL_COND(skeleton->use_2d);23232324float *dataptr = skeleton->data.ptr() + p_bone * 12;23252326dataptr[0] = p_transform.basis.rows[0][0];2327dataptr[1] = p_transform.basis.rows[0][1];2328dataptr[2] = p_transform.basis.rows[0][2];2329dataptr[3] = p_transform.origin.x;2330dataptr[4] = p_transform.basis.rows[1][0];2331dataptr[5] = p_transform.basis.rows[1][1];2332dataptr[6] = p_transform.basis.rows[1][2];2333dataptr[7] = p_transform.origin.y;2334dataptr[8] = p_transform.basis.rows[2][0];2335dataptr[9] = p_transform.basis.rows[2][1];2336dataptr[10] = p_transform.basis.rows[2][2];2337dataptr[11] = p_transform.origin.z;23382339_skeleton_make_dirty(skeleton);2340}23412342Transform3D MeshStorage::skeleton_bone_get_transform(RID p_skeleton, int p_bone) const {2343Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);23442345ERR_FAIL_NULL_V(skeleton, Transform3D());2346ERR_FAIL_INDEX_V(p_bone, skeleton->size, Transform3D());2347ERR_FAIL_COND_V(skeleton->use_2d, Transform3D());23482349const float *dataptr = skeleton->data.ptr() + p_bone * 12;23502351Transform3D t;23522353t.basis.rows[0][0] = dataptr[0];2354t.basis.rows[0][1] = dataptr[1];2355t.basis.rows[0][2] = dataptr[2];2356t.origin.x = dataptr[3];2357t.basis.rows[1][0] = dataptr[4];2358t.basis.rows[1][1] = dataptr[5];2359t.basis.rows[1][2] = dataptr[6];2360t.origin.y = dataptr[7];2361t.basis.rows[2][0] = dataptr[8];2362t.basis.rows[2][1] = dataptr[9];2363t.basis.rows[2][2] = dataptr[10];2364t.origin.z = dataptr[11];23652366return t;2367}23682369void MeshStorage::skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) {2370Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);23712372ERR_FAIL_NULL(skeleton);2373ERR_FAIL_INDEX(p_bone, skeleton->size);2374ERR_FAIL_COND(!skeleton->use_2d);23752376float *dataptr = skeleton->data.ptr() + p_bone * 8;23772378dataptr[0] = p_transform.columns[0][0];2379dataptr[1] = p_transform.columns[1][0];2380dataptr[2] = 0;2381dataptr[3] = p_transform.columns[2][0];2382dataptr[4] = p_transform.columns[0][1];2383dataptr[5] = p_transform.columns[1][1];2384dataptr[6] = 0;2385dataptr[7] = p_transform.columns[2][1];23862387_skeleton_make_dirty(skeleton);2388}23892390Transform2D MeshStorage::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const {2391Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);23922393ERR_FAIL_NULL_V(skeleton, Transform2D());2394ERR_FAIL_INDEX_V(p_bone, skeleton->size, Transform2D());2395ERR_FAIL_COND_V(!skeleton->use_2d, Transform2D());23962397const float *dataptr = skeleton->data.ptr() + p_bone * 8;23982399Transform2D t;2400t.columns[0][0] = dataptr[0];2401t.columns[1][0] = dataptr[1];2402t.columns[2][0] = dataptr[3];2403t.columns[0][1] = dataptr[4];2404t.columns[1][1] = dataptr[5];2405t.columns[2][1] = dataptr[7];24062407return t;2408}24092410void MeshStorage::_update_dirty_skeletons() {2411while (skeleton_dirty_list) {2412Skeleton *skeleton = skeleton_dirty_list;24132414if (skeleton->size) {2415glBindTexture(GL_TEXTURE_2D, skeleton->transforms_texture);2416glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 256, skeleton->height, 0, GL_RGBA, GL_FLOAT, skeleton->data.ptr());2417glBindTexture(GL_TEXTURE_2D, 0);2418}24192420skeleton_dirty_list = skeleton->dirty_list;24212422skeleton->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_SKELETON_BONES);24232424skeleton->version++;24252426skeleton->dirty = false;2427skeleton->dirty_list = nullptr;2428}24292430skeleton_dirty_list = nullptr;2431}24322433void MeshStorage::skeleton_update_dependency(RID p_skeleton, DependencyTracker *p_instance) {2434Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);2435ERR_FAIL_NULL(skeleton);24362437p_instance->update_dependency(&skeleton->dependency);2438}24392440#endif // GLES3_ENABLED244124422443