Path: blob/master/drivers/gles3/storage/mesh_storage.cpp
20784 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, bool p_uses_motion_vectors, MeshInstance::Surface *mis, int p_current_vertex_buffer, int p_prev_vertex_buffer) {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_buffers[p_current_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}10451046if (p_uses_motion_vectors) {1047for (int i = 0; i < RS::ARRAY_TANGENT; i++) {1048if (mis) {1049glBindBuffer(GL_ARRAY_BUFFER, mis->vertex_buffers[mis->prev_vertex_buffer]);1050} else {1051glBindBuffer(GL_ARRAY_BUFFER, s->vertex_buffer);1052}10531054glVertexAttribPointer(i + 16, attribs[i].size, attribs[i].type, attribs[i].normalized, attribs[i].stride, CAST_INT_TO_UCHAR_PTR(attribs[i].offset));1055glEnableVertexAttribArray(i + 16);1056}1057}10581059// Do not bind index here as we want to switch between index buffers for LOD10601061glBindVertexArray(0);1062glBindBuffer(GL_ARRAY_BUFFER, 0);10631064v.input_mask = p_input_mask;1065v.uses_motion_vectors = p_uses_motion_vectors;1066v.current_vertex_buffer = p_current_vertex_buffer;1067v.prev_vertex_buffer = p_prev_vertex_buffer;1068}10691070void MeshStorage::mesh_surface_remove(RID p_mesh, int p_surface) {1071Mesh *mesh = mesh_owner.get_or_null(p_mesh);1072ERR_FAIL_NULL(mesh);1073ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count);10741075// Clear instance data before mesh data.1076for (MeshInstance *mi : mesh->instances) {1077_mesh_instance_remove_surface(mi, p_surface);1078}10791080_mesh_surface_clear(mesh, p_surface);10811082if ((uint32_t)p_surface < mesh->surface_count - 1) {1083memmove(mesh->surfaces + p_surface, mesh->surfaces + p_surface + 1, sizeof(Mesh::Surface *) * (mesh->surface_count - (p_surface + 1)));1084}1085mesh->surfaces = (Mesh::Surface **)memrealloc(mesh->surfaces, sizeof(Mesh::Surface *) * (mesh->surface_count - 1));1086--mesh->surface_count;10871088mesh->material_cache.clear();10891090mesh->skeleton_aabb_version = 0;10911092if (mesh->has_bone_weights) {1093mesh->has_bone_weights = false;1094for (uint32_t i = 0; i < mesh->surface_count; i++) {1095if (mesh->surfaces[i]->format & RS::ARRAY_FORMAT_BONES) {1096mesh->has_bone_weights = true;1097break;1098}1099}1100}11011102if (mesh->surface_count == 0) {1103mesh->aabb = AABB();1104} else {1105mesh->aabb = mesh->surfaces[0]->aabb;1106for (uint32_t i = 1; i < mesh->surface_count; i++) {1107mesh->aabb.merge_with(mesh->surfaces[i]->aabb);1108}1109}11101111mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);11121113for (Mesh *E : mesh->shadow_owners) {1114Mesh *shadow_owner = E;1115shadow_owner->shadow_mesh = RID();1116shadow_owner->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);1117}1118}11191120/* MESH INSTANCE API */11211122RID MeshStorage::mesh_instance_create(RID p_base) {1123Mesh *mesh = mesh_owner.get_or_null(p_base);1124ERR_FAIL_NULL_V(mesh, RID());11251126RID rid = mesh_instance_owner.make_rid();1127MeshInstance *mi = mesh_instance_owner.get_or_null(rid);11281129mi->mesh = mesh;11301131for (uint32_t i = 0; i < mesh->surface_count; i++) {1132_mesh_instance_add_surface(mi, mesh, i);1133}11341135mi->I = mesh->instances.push_back(mi);11361137mi->dirty = true;11381139return rid;1140}11411142void MeshStorage::mesh_instance_free(RID p_rid) {1143MeshInstance *mi = mesh_instance_owner.get_or_null(p_rid);1144_mesh_instance_clear(mi);1145mi->mesh->instances.erase(mi->I);1146mi->I = nullptr;11471148mesh_instance_owner.free(p_rid);1149}11501151void MeshStorage::mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) {1152MeshInstance *mi = mesh_instance_owner.get_or_null(p_mesh_instance);1153if (mi->skeleton == p_skeleton) {1154return;1155}1156mi->skeleton = p_skeleton;1157mi->skeleton_version = 0;1158mi->dirty = true;1159}11601161void MeshStorage::mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int p_shape, float p_weight) {1162MeshInstance *mi = mesh_instance_owner.get_or_null(p_mesh_instance);1163ERR_FAIL_NULL(mi);1164ERR_FAIL_INDEX(p_shape, (int)mi->blend_weights.size());1165mi->blend_weights[p_shape] = p_weight;1166mi->dirty = true;1167}11681169void MeshStorage::_mesh_instance_clear(MeshInstance *mi) {1170while (mi->surfaces.size()) {1171_mesh_instance_remove_surface(mi, mi->surfaces.size() - 1);1172}1173mi->dirty = false;1174}11751176void MeshStorage::_mesh_instance_add_surface(MeshInstance *mi, Mesh *mesh, uint32_t p_surface) {1177if (mesh->blend_shape_count > 0) {1178mi->blend_weights.resize(mesh->blend_shape_count);1179for (uint32_t i = 0; i < mi->blend_weights.size(); i++) {1180mi->blend_weights[i] = 0.0;1181}1182}11831184MeshInstance::Surface s;1185if ((mesh->blend_shape_count > 0 || (mesh->surfaces[p_surface]->format & RS::ARRAY_FORMAT_BONES)) && mesh->surfaces[p_surface]->vertex_buffer_size > 0) {1186// Cache surface properties1187s.format_cache = mesh->surfaces[p_surface]->format;1188if ((s.format_cache & (1ULL << RS::ARRAY_VERTEX))) {1189if (s.format_cache & RS::ARRAY_FLAG_USE_2D_VERTICES) {1190s.vertex_size_cache = 2;1191} else {1192s.vertex_size_cache = 3;1193}1194s.vertex_stride_cache = sizeof(float) * s.vertex_size_cache;1195}1196if ((s.format_cache & (1ULL << RS::ARRAY_NORMAL))) {1197s.vertex_normal_offset_cache = s.vertex_stride_cache;1198s.vertex_stride_cache += sizeof(uint32_t) * 2;1199}1200if ((s.format_cache & (1ULL << RS::ARRAY_TANGENT))) {1201s.vertex_tangent_offset_cache = s.vertex_stride_cache;1202s.vertex_stride_cache += sizeof(uint32_t) * 2;1203}12041205int buffer_size = s.vertex_stride_cache * mesh->surfaces[p_surface]->vertex_count;12061207// First buffer to be used for rendering. Final output of skeleton and blend shapes.1208// If motion vectors are enabled, a second buffer will be created on demand, and they'll be swapped every frame.1209glGenBuffers(1, &s.vertex_buffers[0]);1210glBindBuffer(GL_ARRAY_BUFFER, s.vertex_buffers[0]);1211GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s.vertex_buffers[0], buffer_size, nullptr, GL_DYNAMIC_DRAW, "MeshInstance vertex buffer");1212if (mesh->blend_shape_count > 0) {1213// Ping-Pong buffers for processing blendshapes.1214glGenBuffers(2, s.blend_shape_vertex_buffers);1215for (uint32_t i = 0; i < 2; i++) {1216glBindBuffer(GL_ARRAY_BUFFER, s.blend_shape_vertex_buffers[i]);1217GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s.blend_shape_vertex_buffers[i], buffer_size, nullptr, GL_DYNAMIC_DRAW, "MeshInstance process buffer[" + itos(i) + "]");1218}1219}1220glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind1221}12221223mi->surfaces.push_back(s);1224mi->dirty = true;1225}12261227void MeshStorage::_mesh_instance_remove_surface(MeshInstance *mi, int p_surface) {1228MeshInstance::Surface &surface = mi->surfaces[p_surface];12291230if (surface.version_count != 0) {1231for (uint32_t j = 0; j < surface.version_count; j++) {1232glDeleteVertexArrays(1, &surface.versions[j].vertex_array);1233surface.versions[j].vertex_array = 0;1234}1235memfree(surface.versions);1236}12371238if (surface.blend_shape_vertex_buffers[0] != 0) {1239GLES3::Utilities::get_singleton()->buffer_free_data(surface.blend_shape_vertex_buffers[0]);1240GLES3::Utilities::get_singleton()->buffer_free_data(surface.blend_shape_vertex_buffers[1]);1241surface.blend_shape_vertex_buffers[0] = 0;1242surface.blend_shape_vertex_buffers[1] = 0;1243}12441245for (int i = 0; i < 2; i++) {1246if (surface.vertex_buffers[i] != 0) {1247GLES3::Utilities::get_singleton()->buffer_free_data(surface.vertex_buffers[i]);1248surface.vertex_buffers[i] = 0;1249}1250}12511252mi->surfaces.remove_at(p_surface);12531254if (mi->surfaces.is_empty()) {1255mi->blend_weights.clear();1256mi->weights_dirty = false;1257mi->skeleton_version = 0;1258}1259mi->dirty = true;1260}12611262void MeshStorage::mesh_instance_check_for_update(RID p_mesh_instance) {1263MeshInstance *mi = mesh_instance_owner.get_or_null(p_mesh_instance);12641265bool needs_update = mi->dirty;12661267if (mi->array_update_list.in_list()) {1268return;1269}12701271if (!needs_update && mi->skeleton.is_valid()) {1272Skeleton *sk = skeleton_owner.get_or_null(mi->skeleton);1273if (sk && sk->version != mi->skeleton_version) {1274needs_update = true;1275}1276}12771278if (needs_update) {1279dirty_mesh_instance_arrays.add(&mi->array_update_list);1280}1281}12821283void MeshStorage::mesh_instance_set_canvas_item_transform(RID p_mesh_instance, const Transform2D &p_transform) {1284MeshInstance *mi = mesh_instance_owner.get_or_null(p_mesh_instance);1285mi->canvas_item_transform_2d = p_transform;1286}12871288void MeshStorage::_blend_shape_bind_mesh_instance_buffer(MeshInstance *p_mi, uint32_t p_surface) {1289glBindBuffer(GL_ARRAY_BUFFER, p_mi->surfaces[p_surface].blend_shape_vertex_buffers[0]);12901291if ((p_mi->surfaces[p_surface].format_cache & (1ULL << RS::ARRAY_VERTEX))) {1292glEnableVertexAttribArray(RS::ARRAY_VERTEX);1293glVertexAttribPointer(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));1294} else {1295glDisableVertexAttribArray(RS::ARRAY_VERTEX);1296}1297if ((p_mi->surfaces[p_surface].format_cache & (1ULL << RS::ARRAY_NORMAL))) {1298glEnableVertexAttribArray(RS::ARRAY_NORMAL);1299glVertexAttribIPointer(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));1300} else {1301glDisableVertexAttribArray(RS::ARRAY_NORMAL);1302}1303if ((p_mi->surfaces[p_surface].format_cache & (1ULL << RS::ARRAY_TANGENT))) {1304glEnableVertexAttribArray(RS::ARRAY_TANGENT);1305glVertexAttribIPointer(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));1306} else {1307glDisableVertexAttribArray(RS::ARRAY_TANGENT);1308}1309}13101311void MeshStorage::_compute_skeleton(MeshInstance *p_mi, Skeleton *p_sk, uint32_t p_surface) {1312// Add in the bones and weights.1313glBindBuffer(GL_ARRAY_BUFFER, p_mi->mesh->surfaces[p_surface]->skin_buffer);13141315bool use_8_weights = p_mi->surfaces[p_surface].format_cache & RS::ARRAY_FLAG_USE_8_BONE_WEIGHTS;1316int skin_stride = sizeof(int16_t) * (use_8_weights ? 16 : 8);1317glEnableVertexAttribArray(RS::ARRAY_BONES);1318glVertexAttribIPointer(RS::ARRAY_BONES, 4, GL_UNSIGNED_SHORT, skin_stride, CAST_INT_TO_UCHAR_PTR(0));1319if (use_8_weights) {1320glEnableVertexAttribArray(11);1321glVertexAttribIPointer(11, 4, GL_UNSIGNED_SHORT, skin_stride, CAST_INT_TO_UCHAR_PTR(4 * sizeof(uint16_t)));1322glEnableVertexAttribArray(12);1323glVertexAttribPointer(12, 4, GL_UNSIGNED_SHORT, GL_TRUE, skin_stride, CAST_INT_TO_UCHAR_PTR(8 * sizeof(uint16_t)));1324glEnableVertexAttribArray(13);1325glVertexAttribPointer(13, 4, GL_UNSIGNED_SHORT, GL_TRUE, skin_stride, CAST_INT_TO_UCHAR_PTR(12 * sizeof(uint16_t)));1326} else {1327glEnableVertexAttribArray(RS::ARRAY_WEIGHTS);1328glVertexAttribPointer(RS::ARRAY_WEIGHTS, 4, GL_UNSIGNED_SHORT, GL_TRUE, skin_stride, CAST_INT_TO_UCHAR_PTR(4 * sizeof(uint16_t)));1329}13301331glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, p_mi->surfaces[p_surface].vertex_buffers[p_mi->surfaces[p_surface].current_vertex_buffer]);1332glActiveTexture(GL_TEXTURE0);1333glBindTexture(GL_TEXTURE_2D, p_sk->transforms_texture);13341335glBeginTransformFeedback(GL_POINTS);1336glDrawArrays(GL_POINTS, 0, p_mi->mesh->surfaces[p_surface]->vertex_count);1337glEndTransformFeedback();13381339glDisableVertexAttribArray(RS::ARRAY_BONES);1340glDisableVertexAttribArray(RS::ARRAY_WEIGHTS);1341glDisableVertexAttribArray(RS::ARRAY_BONES + 2);1342glDisableVertexAttribArray(RS::ARRAY_WEIGHTS + 2);1343glBindVertexArray(0);1344glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);1345}13461347void MeshStorage::update_mesh_instances() {1348if (dirty_mesh_instance_arrays.first() == nullptr) {1349return; //nothing to do1350}13511352glEnable(GL_RASTERIZER_DISCARD);1353glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);1354// Process skeletons and blend shapes using transform feedback1355while (dirty_mesh_instance_arrays.first()) {1356MeshInstance *mi = dirty_mesh_instance_arrays.first()->self();13571358bool uses_motion_vectors = RSG::viewport->get_num_viewports_with_motion_vectors() > 0;1359int frame = RSG::rasterizer->get_frame_number();1360if (uses_motion_vectors) {1361for (uint32_t i = 0; i < mi->surfaces.size(); i++) {1362mi->surfaces[i].prev_vertex_buffer = mi->surfaces[i].current_vertex_buffer;13631364if (frame - mi->surfaces[i].last_change == 1) {1365// Previous buffer's data can only be one frame old to be able to use motion vectors.1366uint32_t new_buffer_index = mi->surfaces[i].current_vertex_buffer ^ 1;13671368if (mi->surfaces[i].vertex_buffers[new_buffer_index] == 0) {1369// Create the new vertex buffer on demand where the result for the current frame will be stored.1370GLuint new_vertex_buffer = 0;1371GLES3::Mesh::Surface *surface = mi->mesh->surfaces[i];1372int buffer_size = mi->surfaces[i].vertex_stride_cache * surface->vertex_count;1373glGenBuffers(1, &new_vertex_buffer);1374glBindBuffer(GL_ARRAY_BUFFER, new_vertex_buffer);1375GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, new_vertex_buffer, buffer_size, nullptr, (surface->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW, "Secondary mesh vertex buffer");1376glBindBuffer(GL_ARRAY_BUFFER, 0);13771378mi->surfaces[i].vertex_buffers[new_buffer_index] = new_vertex_buffer;1379}13801381mi->surfaces[i].current_vertex_buffer = new_buffer_index;1382}13831384mi->surfaces[i].last_change = frame;1385}1386}13871388Skeleton *sk = skeleton_owner.get_or_null(mi->skeleton);13891390// Precompute base weight if using blend shapes.1391float base_weight = 1.0;1392if (mi->surfaces.size() && mi->mesh->blend_shape_count && mi->mesh->blend_shape_mode == RS::BLEND_SHAPE_MODE_NORMALIZED) {1393for (uint32_t i = 0; i < mi->mesh->blend_shape_count; i++) {1394base_weight -= mi->blend_weights[i];1395}1396}13971398for (uint32_t i = 0; i < mi->surfaces.size(); i++) {1399if (mi->surfaces[i].vertex_buffers[mi->surfaces[i].current_vertex_buffer] == 0) {1400continue;1401}14021403bool array_is_2d = mi->surfaces[i].format_cache & RS::ARRAY_FLAG_USE_2D_VERTICES;1404bool can_use_skeleton = sk != nullptr && sk->use_2d == array_is_2d && (mi->surfaces[i].format_cache & RS::ARRAY_FORMAT_BONES);1405bool use_8_weights = mi->surfaces[i].format_cache & RS::ARRAY_FLAG_USE_8_BONE_WEIGHTS;14061407// Always process blend shapes first.1408if (mi->mesh->blend_shape_count) {1409SkeletonShaderGLES3::ShaderVariant variant = SkeletonShaderGLES3::MODE_BASE_PASS;1410uint64_t specialization = 0;1411specialization |= array_is_2d ? SkeletonShaderGLES3::MODE_2D : 0;1412specialization |= SkeletonShaderGLES3::USE_BLEND_SHAPES;1413if (!array_is_2d) {1414if ((mi->surfaces[i].format_cache & (1ULL << RS::ARRAY_NORMAL))) {1415specialization |= SkeletonShaderGLES3::USE_NORMAL;1416}1417if ((mi->surfaces[i].format_cache & (1ULL << RS::ARRAY_TANGENT))) {1418specialization |= SkeletonShaderGLES3::USE_TANGENT;1419}1420}14211422bool success = skeleton_shader.shader.version_bind_shader(skeleton_shader.shader_version, variant, specialization);1423if (!success) {1424continue;1425}14261427skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::BLEND_WEIGHT, base_weight, skeleton_shader.shader_version, variant, specialization);1428skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::BLEND_SHAPE_COUNT, float(mi->mesh->blend_shape_count), skeleton_shader.shader_version, variant, specialization);14291430glBindBuffer(GL_ARRAY_BUFFER, 0);1431GLuint vertex_array_gl = 0;1432uint64_t mask = RS::ARRAY_FORMAT_VERTEX | RS::ARRAY_FORMAT_NORMAL | RS::ARRAY_FORMAT_VERTEX;1433uint64_t format = mi->mesh->surfaces[i]->format & mask; // Format should only have vertex, normal, tangent (as necessary).1434mesh_surface_get_vertex_arrays_and_format(mi->mesh->surfaces[i], format, false, vertex_array_gl);1435glBindVertexArray(vertex_array_gl);1436glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mi->surfaces[i].blend_shape_vertex_buffers[0]);1437glBeginTransformFeedback(GL_POINTS);1438glDrawArrays(GL_POINTS, 0, mi->mesh->surfaces[i]->vertex_count);1439glEndTransformFeedback();14401441variant = SkeletonShaderGLES3::MODE_BLEND_PASS;1442success = skeleton_shader.shader.version_bind_shader(skeleton_shader.shader_version, variant, specialization);1443if (!success) {1444continue;1445}14461447//Do the last blend shape separately, as it can be combined with the skeleton pass.1448for (uint32_t bs = 0; bs < mi->mesh->blend_shape_count - 1; bs++) {1449float weight = mi->blend_weights[bs];14501451if (Math::is_zero_approx(weight)) {1452//not bother with this one1453continue;1454}1455skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::BLEND_WEIGHT, weight, skeleton_shader.shader_version, variant, specialization);1456skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::BLEND_SHAPE_COUNT, float(mi->mesh->blend_shape_count), skeleton_shader.shader_version, variant, specialization);14571458// Ensure the skeleton shader outputs to the correct (current) VBO.14591460glBindVertexArray(mi->mesh->surfaces[i]->blend_shapes[bs].vertex_array);1461_blend_shape_bind_mesh_instance_buffer(mi, i);1462glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mi->surfaces[i].blend_shape_vertex_buffers[1]);14631464glBeginTransformFeedback(GL_POINTS);1465glDrawArrays(GL_POINTS, 0, mi->mesh->surfaces[i]->vertex_count);1466glEndTransformFeedback();14671468SWAP(mi->surfaces[i].blend_shape_vertex_buffers[0], mi->surfaces[i].blend_shape_vertex_buffers[1]);1469}1470uint32_t bs = mi->mesh->blend_shape_count - 1;14711472float weight = mi->blend_weights[bs];14731474glBindVertexArray(mi->mesh->surfaces[i]->blend_shapes[bs].vertex_array);1475_blend_shape_bind_mesh_instance_buffer(mi, i);14761477specialization |= can_use_skeleton ? SkeletonShaderGLES3::USE_SKELETON : 0;1478specialization |= (can_use_skeleton && use_8_weights) ? SkeletonShaderGLES3::USE_EIGHT_WEIGHTS : 0;1479specialization |= SkeletonShaderGLES3::FINAL_PASS;1480success = skeleton_shader.shader.version_bind_shader(skeleton_shader.shader_version, variant, specialization);1481if (!success) {1482continue;1483}14841485skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::BLEND_WEIGHT, weight, skeleton_shader.shader_version, variant, specialization);1486skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::BLEND_SHAPE_COUNT, float(mi->mesh->blend_shape_count), skeleton_shader.shader_version, variant, specialization);14871488if (can_use_skeleton) {1489Transform2D transform = mi->canvas_item_transform_2d.affine_inverse() * sk->base_transform_2d;1490skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::SKELETON_TRANSFORM_X, transform[0], skeleton_shader.shader_version, variant, specialization);1491skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::SKELETON_TRANSFORM_Y, transform[1], skeleton_shader.shader_version, variant, specialization);1492skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::SKELETON_TRANSFORM_OFFSET, transform[2], skeleton_shader.shader_version, variant, specialization);14931494Transform2D inverse_transform = transform.affine_inverse();1495skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_X, inverse_transform[0], skeleton_shader.shader_version, variant, specialization);1496skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_Y, inverse_transform[1], skeleton_shader.shader_version, variant, specialization);1497skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_OFFSET, inverse_transform[2], skeleton_shader.shader_version, variant, specialization);14981499// Do last blendshape in the same pass as the Skeleton.1500_compute_skeleton(mi, sk, i);1501can_use_skeleton = false;1502} else {1503// Do last blendshape by itself and prepare vertex data for use by the renderer.1504glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mi->surfaces[i].vertex_buffers[mi->surfaces[i].current_vertex_buffer]);15051506glBeginTransformFeedback(GL_POINTS);1507glDrawArrays(GL_POINTS, 0, mi->mesh->surfaces[i]->vertex_count);1508glEndTransformFeedback();1509}15101511glBindVertexArray(0);1512glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);1513}15141515// This branch should only execute when Skeleton is run by itself.1516if (can_use_skeleton) {1517SkeletonShaderGLES3::ShaderVariant variant = SkeletonShaderGLES3::MODE_BASE_PASS;1518uint64_t specialization = 0;1519specialization |= array_is_2d ? SkeletonShaderGLES3::MODE_2D : 0;1520specialization |= SkeletonShaderGLES3::USE_SKELETON;1521specialization |= SkeletonShaderGLES3::FINAL_PASS;1522specialization |= use_8_weights ? SkeletonShaderGLES3::USE_EIGHT_WEIGHTS : 0;1523if (!array_is_2d) {1524if ((mi->surfaces[i].format_cache & (1ULL << RS::ARRAY_NORMAL))) {1525specialization |= SkeletonShaderGLES3::USE_NORMAL;1526}1527if ((mi->surfaces[i].format_cache & (1ULL << RS::ARRAY_TANGENT))) {1528specialization |= SkeletonShaderGLES3::USE_TANGENT;1529}1530}15311532bool success = skeleton_shader.shader.version_bind_shader(skeleton_shader.shader_version, variant, specialization);1533if (!success) {1534continue;1535}15361537Transform2D transform = mi->canvas_item_transform_2d.affine_inverse() * sk->base_transform_2d;1538skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::SKELETON_TRANSFORM_X, transform[0], skeleton_shader.shader_version, variant, specialization);1539skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::SKELETON_TRANSFORM_Y, transform[1], skeleton_shader.shader_version, variant, specialization);1540skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::SKELETON_TRANSFORM_OFFSET, transform[2], skeleton_shader.shader_version, variant, specialization);15411542Transform2D inverse_transform = transform.affine_inverse();1543skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_X, inverse_transform[0], skeleton_shader.shader_version, variant, specialization);1544skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_Y, inverse_transform[1], skeleton_shader.shader_version, variant, specialization);1545skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_OFFSET, inverse_transform[2], skeleton_shader.shader_version, variant, specialization);15461547GLuint vertex_array_gl = 0;1548uint64_t mask = RS::ARRAY_FORMAT_VERTEX | RS::ARRAY_FORMAT_NORMAL | RS::ARRAY_FORMAT_VERTEX;1549uint64_t format = mi->mesh->surfaces[i]->format & mask; // Format should only have vertex, normal, tangent (as necessary).1550mesh_surface_get_vertex_arrays_and_format(mi->mesh->surfaces[i], format, false, vertex_array_gl);1551glBindVertexArray(vertex_array_gl);1552_compute_skeleton(mi, sk, i);1553}1554}1555mi->dirty = false;1556if (sk) {1557mi->skeleton_version = sk->version;1558}1559dirty_mesh_instance_arrays.remove(&mi->array_update_list);1560}1561glDisable(GL_RASTERIZER_DISCARD);1562glBindBuffer(GL_ARRAY_BUFFER, 0);1563glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);1564}15651566/* MULTIMESH API */15671568RID MeshStorage::_multimesh_allocate() {1569return multimesh_owner.allocate_rid();1570}15711572void MeshStorage::_multimesh_initialize(RID p_rid) {1573multimesh_owner.initialize_rid(p_rid, MultiMesh());1574}15751576void MeshStorage::_multimesh_free(RID p_rid) {1577// Remove from interpolator.1578_interpolation_data.notify_free_multimesh(p_rid);1579_update_dirty_multimeshes();1580multimesh_allocate_data(p_rid, 0, RS::MULTIMESH_TRANSFORM_2D);1581MultiMesh *multimesh = multimesh_owner.get_or_null(p_rid);1582multimesh->dependency.deleted_notify(p_rid);1583multimesh_owner.free(p_rid);1584}15851586void 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) {1587MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1588ERR_FAIL_NULL(multimesh);15891590if (multimesh->instances == p_instances && multimesh->xform_format == p_transform_format && multimesh->uses_colors == p_use_colors && multimesh->uses_custom_data == p_use_custom_data) {1591return;1592}15931594for (int i = 0; i < 2; i++) {1595if (multimesh->buffer[i] != 0) {1596GLES3::Utilities::get_singleton()->buffer_free_data(multimesh->buffer[i]);1597multimesh->buffer[i] = 0;1598}1599}16001601if (multimesh->data_cache_dirty_regions) {1602memdelete_arr(multimesh->data_cache_dirty_regions);1603multimesh->data_cache_dirty_regions = nullptr;1604multimesh->data_cache_used_dirty_regions = 0;1605}16061607// If we have either color or custom data, reserve space for both to make data handling logic simpler.1608// This way we can always treat them both as a single, compressed uvec4.1609int color_and_custom_strides = (p_use_colors || p_use_custom_data) ? 2 : 0;16101611multimesh->instances = p_instances;1612multimesh->xform_format = p_transform_format;1613multimesh->uses_colors = p_use_colors;1614multimesh->color_offset_cache = p_transform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12;1615multimesh->uses_custom_data = p_use_custom_data;1616multimesh->custom_data_offset_cache = multimesh->color_offset_cache + color_and_custom_strides;1617multimesh->stride_cache = multimesh->custom_data_offset_cache + color_and_custom_strides;1618multimesh->buffer_set = false;16191620multimesh->data_cache = Vector<float>();1621multimesh->aabb = AABB();1622multimesh->aabb_dirty = false;1623multimesh->visible_instances = MIN(multimesh->visible_instances, multimesh->instances);16241625if (multimesh->instances) {1626glGenBuffers(1, &multimesh->buffer[0]);1627glBindBuffer(GL_ARRAY_BUFFER, multimesh->buffer[0]);1628GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, multimesh->buffer[0], multimesh->instances * multimesh->stride_cache * sizeof(float), nullptr, GL_STATIC_DRAW, "MultiMesh buffer");1629glBindBuffer(GL_ARRAY_BUFFER, 0);1630}16311632multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MULTIMESH);1633}16341635int MeshStorage::_multimesh_get_instance_count(RID p_multimesh) const {1636MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1637ERR_FAIL_NULL_V(multimesh, 0);1638return multimesh->instances;1639}16401641void MeshStorage::_multimesh_set_mesh(RID p_multimesh, RID p_mesh) {1642MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1643ERR_FAIL_NULL(multimesh);1644if (multimesh->mesh == p_mesh || p_mesh.is_null()) {1645return;1646}1647multimesh->mesh = p_mesh;16481649if (multimesh->instances == 0) {1650return;1651}16521653if (multimesh->data_cache.size()) {1654//we have a data cache, just mark it dirty1655_multimesh_mark_all_dirty(multimesh, false, true);1656} else if (multimesh->instances) {1657// Need to re-create AABB. Unfortunately, calling this has a penalty.1658if (multimesh->buffer_set) {1659Vector<uint8_t> buffer = Utilities::buffer_get_data(GL_ARRAY_BUFFER, multimesh->buffer[multimesh->current_buffer], multimesh->instances * multimesh->stride_cache * sizeof(float));1660const uint8_t *r = buffer.ptr();1661const float *data = (const float *)r;1662_multimesh_re_create_aabb(multimesh, data, multimesh->instances);1663}1664}16651666multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);1667}16681669#define MULTIMESH_DIRTY_REGION_SIZE 51216701671void MeshStorage::_multimesh_make_local(MultiMesh *multimesh) const {1672if (multimesh->data_cache.size() > 0 || multimesh->instances == 0) {1673return; //already local1674}1675ERR_FAIL_COND(multimesh->data_cache.size() > 0);1676// this means that the user wants to load/save individual elements,1677// for this, the data must reside on CPU, so just copy it there.1678multimesh->data_cache.resize(multimesh->instances * multimesh->stride_cache);1679{1680float *w = multimesh->data_cache.ptrw();16811682if (multimesh->buffer_set) {1683Vector<uint8_t> buffer = Utilities::buffer_get_data(GL_ARRAY_BUFFER, multimesh->buffer[multimesh->current_buffer], multimesh->instances * multimesh->stride_cache * sizeof(float));16841685{1686const uint8_t *r = buffer.ptr();1687memcpy(w, r, buffer.size());1688}1689} else {1690memset(w, 0, (size_t)multimesh->instances * multimesh->stride_cache * sizeof(float));1691}1692}1693uint32_t data_cache_dirty_region_count = Math::division_round_up(multimesh->instances, MULTIMESH_DIRTY_REGION_SIZE);1694multimesh->data_cache_dirty_regions = memnew_arr(bool, data_cache_dirty_region_count);1695for (uint32_t i = 0; i < data_cache_dirty_region_count; i++) {1696multimesh->data_cache_dirty_regions[i] = false;1697}1698multimesh->data_cache_used_dirty_regions = 0;1699}17001701void MeshStorage::_multimesh_mark_dirty(MultiMesh *multimesh, int p_index, bool p_aabb) {1702uint32_t region_index = p_index / MULTIMESH_DIRTY_REGION_SIZE;1703#ifdef DEBUG_ENABLED1704uint32_t data_cache_dirty_region_count = Math::division_round_up(multimesh->instances, MULTIMESH_DIRTY_REGION_SIZE);1705ERR_FAIL_UNSIGNED_INDEX(region_index, data_cache_dirty_region_count); //bug1706#endif1707if (!multimesh->data_cache_dirty_regions[region_index]) {1708multimesh->data_cache_dirty_regions[region_index] = true;1709multimesh->data_cache_used_dirty_regions++;1710}17111712if (p_aabb) {1713multimesh->aabb_dirty = true;1714}17151716if (!multimesh->dirty) {1717multimesh->dirty_list = multimesh_dirty_list;1718multimesh_dirty_list = multimesh;1719multimesh->dirty = true;1720}1721}17221723void MeshStorage::_multimesh_mark_all_dirty(MultiMesh *multimesh, bool p_data, bool p_aabb) {1724if (p_data) {1725uint32_t data_cache_dirty_region_count = Math::division_round_up(multimesh->instances, MULTIMESH_DIRTY_REGION_SIZE);17261727for (uint32_t i = 0; i < data_cache_dirty_region_count; i++) {1728if (!multimesh->data_cache_dirty_regions[i]) {1729multimesh->data_cache_dirty_regions[i] = true;1730multimesh->data_cache_used_dirty_regions++;1731}1732}1733}17341735if (p_aabb) {1736multimesh->aabb_dirty = true;1737}17381739if (!multimesh->dirty) {1740multimesh->dirty_list = multimesh_dirty_list;1741multimesh_dirty_list = multimesh;1742multimesh->dirty = true;1743}1744}17451746void MeshStorage::_multimesh_re_create_aabb(MultiMesh *multimesh, const float *p_data, int p_instances) {1747ERR_FAIL_COND(multimesh->mesh.is_null());1748if (multimesh->custom_aabb != AABB()) {1749return;1750}1751AABB aabb;1752AABB mesh_aabb = mesh_get_aabb(multimesh->mesh);1753for (int i = 0; i < p_instances; i++) {1754const float *data = p_data + multimesh->stride_cache * i;1755Transform3D t;17561757if (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_3D) {1758t.basis.rows[0][0] = data[0];1759t.basis.rows[0][1] = data[1];1760t.basis.rows[0][2] = data[2];1761t.origin.x = data[3];1762t.basis.rows[1][0] = data[4];1763t.basis.rows[1][1] = data[5];1764t.basis.rows[1][2] = data[6];1765t.origin.y = data[7];1766t.basis.rows[2][0] = data[8];1767t.basis.rows[2][1] = data[9];1768t.basis.rows[2][2] = data[10];1769t.origin.z = data[11];17701771} else {1772t.basis.rows[0][0] = data[0];1773t.basis.rows[0][1] = data[1];1774t.origin.x = data[3];17751776t.basis.rows[1][0] = data[4];1777t.basis.rows[1][1] = data[5];1778t.origin.y = data[7];1779}17801781if (i == 0) {1782aabb = t.xform(mesh_aabb);1783} else {1784aabb.merge_with(t.xform(mesh_aabb));1785}1786}17871788multimesh->aabb = aabb;1789}17901791void MeshStorage::_multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform3D &p_transform) {1792MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1793ERR_FAIL_NULL(multimesh);1794ERR_FAIL_INDEX(p_index, multimesh->instances);1795ERR_FAIL_COND(multimesh->xform_format != RS::MULTIMESH_TRANSFORM_3D);17961797_multimesh_make_local(multimesh);17981799{1800float *w = multimesh->data_cache.ptrw();18011802float *dataptr = w + p_index * multimesh->stride_cache;18031804dataptr[0] = p_transform.basis.rows[0][0];1805dataptr[1] = p_transform.basis.rows[0][1];1806dataptr[2] = p_transform.basis.rows[0][2];1807dataptr[3] = p_transform.origin.x;1808dataptr[4] = p_transform.basis.rows[1][0];1809dataptr[5] = p_transform.basis.rows[1][1];1810dataptr[6] = p_transform.basis.rows[1][2];1811dataptr[7] = p_transform.origin.y;1812dataptr[8] = p_transform.basis.rows[2][0];1813dataptr[9] = p_transform.basis.rows[2][1];1814dataptr[10] = p_transform.basis.rows[2][2];1815dataptr[11] = p_transform.origin.z;1816}18171818_multimesh_mark_dirty(multimesh, p_index, true);1819}18201821void MeshStorage::_multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) {1822MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1823ERR_FAIL_NULL(multimesh);1824ERR_FAIL_INDEX(p_index, multimesh->instances);1825ERR_FAIL_COND(multimesh->xform_format != RS::MULTIMESH_TRANSFORM_2D);18261827_multimesh_make_local(multimesh);18281829{1830float *w = multimesh->data_cache.ptrw();18311832float *dataptr = w + p_index * multimesh->stride_cache;18331834dataptr[0] = p_transform.columns[0][0];1835dataptr[1] = p_transform.columns[1][0];1836dataptr[2] = 0;1837dataptr[3] = p_transform.columns[2][0];1838dataptr[4] = p_transform.columns[0][1];1839dataptr[5] = p_transform.columns[1][1];1840dataptr[6] = 0;1841dataptr[7] = p_transform.columns[2][1];1842}18431844_multimesh_mark_dirty(multimesh, p_index, true);1845}18461847void MeshStorage::_multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) {1848MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1849ERR_FAIL_NULL(multimesh);1850ERR_FAIL_INDEX(p_index, multimesh->instances);1851ERR_FAIL_COND(!multimesh->uses_colors);18521853_multimesh_make_local(multimesh);18541855{1856// Colors are packed into 2 floats.1857float *w = multimesh->data_cache.ptrw();18581859float *dataptr = w + p_index * multimesh->stride_cache + multimesh->color_offset_cache;1860uint16_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) };1861memcpy(dataptr, val, 2 * 4);1862}18631864_multimesh_mark_dirty(multimesh, p_index, false);1865}18661867void MeshStorage::_multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) {1868MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1869ERR_FAIL_NULL(multimesh);1870ERR_FAIL_INDEX(p_index, multimesh->instances);1871ERR_FAIL_COND(!multimesh->uses_custom_data);18721873_multimesh_make_local(multimesh);18741875{1876float *w = multimesh->data_cache.ptrw();18771878float *dataptr = w + p_index * multimesh->stride_cache + multimesh->custom_data_offset_cache;1879uint16_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) };1880memcpy(dataptr, val, 2 * 4);1881}18821883_multimesh_mark_dirty(multimesh, p_index, false);1884}18851886RID MeshStorage::_multimesh_get_mesh(RID p_multimesh) const {1887MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1888ERR_FAIL_NULL_V(multimesh, RID());18891890return multimesh->mesh;1891}18921893void MeshStorage::_multimesh_set_custom_aabb(RID p_multimesh, const AABB &p_aabb) {1894MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1895ERR_FAIL_NULL(multimesh);1896multimesh->custom_aabb = p_aabb;1897multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);1898}18991900AABB MeshStorage::_multimesh_get_custom_aabb(RID p_multimesh) const {1901MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1902ERR_FAIL_NULL_V(multimesh, AABB());1903return multimesh->custom_aabb;1904}19051906AABB MeshStorage::_multimesh_get_aabb(RID p_multimesh) {1907MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1908ERR_FAIL_NULL_V(multimesh, AABB());1909if (multimesh->custom_aabb != AABB()) {1910return multimesh->custom_aabb;1911}1912if (multimesh->aabb_dirty) {1913_update_dirty_multimeshes();1914}1915return multimesh->aabb;1916}19171918Transform3D MeshStorage::_multimesh_instance_get_transform(RID p_multimesh, int p_index) const {1919MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1920ERR_FAIL_NULL_V(multimesh, Transform3D());1921ERR_FAIL_INDEX_V(p_index, multimesh->instances, Transform3D());1922ERR_FAIL_COND_V(multimesh->xform_format != RS::MULTIMESH_TRANSFORM_3D, Transform3D());19231924_multimesh_make_local(multimesh);19251926Transform3D t;1927{1928const float *r = multimesh->data_cache.ptr();19291930const float *dataptr = r + p_index * multimesh->stride_cache;19311932t.basis.rows[0][0] = dataptr[0];1933t.basis.rows[0][1] = dataptr[1];1934t.basis.rows[0][2] = dataptr[2];1935t.origin.x = dataptr[3];1936t.basis.rows[1][0] = dataptr[4];1937t.basis.rows[1][1] = dataptr[5];1938t.basis.rows[1][2] = dataptr[6];1939t.origin.y = dataptr[7];1940t.basis.rows[2][0] = dataptr[8];1941t.basis.rows[2][1] = dataptr[9];1942t.basis.rows[2][2] = dataptr[10];1943t.origin.z = dataptr[11];1944}19451946return t;1947}19481949Transform2D MeshStorage::_multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const {1950MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1951ERR_FAIL_NULL_V(multimesh, Transform2D());1952ERR_FAIL_INDEX_V(p_index, multimesh->instances, Transform2D());1953ERR_FAIL_COND_V(multimesh->xform_format != RS::MULTIMESH_TRANSFORM_2D, Transform2D());19541955_multimesh_make_local(multimesh);19561957Transform2D t;1958{1959const float *r = multimesh->data_cache.ptr();19601961const float *dataptr = r + p_index * multimesh->stride_cache;19621963t.columns[0][0] = dataptr[0];1964t.columns[1][0] = dataptr[1];1965t.columns[2][0] = dataptr[3];1966t.columns[0][1] = dataptr[4];1967t.columns[1][1] = dataptr[5];1968t.columns[2][1] = dataptr[7];1969}19701971return t;1972}19731974Color MeshStorage::_multimesh_instance_get_color(RID p_multimesh, int p_index) const {1975MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);1976ERR_FAIL_NULL_V(multimesh, Color());1977ERR_FAIL_INDEX_V(p_index, multimesh->instances, Color());1978ERR_FAIL_COND_V(!multimesh->uses_colors, Color());19791980_multimesh_make_local(multimesh);19811982Color c;1983{1984const float *r = multimesh->data_cache.ptr();19851986const float *dataptr = r + p_index * multimesh->stride_cache + multimesh->color_offset_cache;1987uint16_t raw_data[4];1988memcpy(raw_data, dataptr, 2 * 4);1989c.r = Math::half_to_float(raw_data[0]);1990c.g = Math::half_to_float(raw_data[1]);1991c.b = Math::half_to_float(raw_data[2]);1992c.a = Math::half_to_float(raw_data[3]);1993}19941995return c;1996}19971998Color MeshStorage::_multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const {1999MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);2000ERR_FAIL_NULL_V(multimesh, Color());2001ERR_FAIL_INDEX_V(p_index, multimesh->instances, Color());2002ERR_FAIL_COND_V(!multimesh->uses_custom_data, Color());20032004_multimesh_make_local(multimesh);20052006Color c;2007{2008const float *r = multimesh->data_cache.ptr();20092010const float *dataptr = r + p_index * multimesh->stride_cache + multimesh->custom_data_offset_cache;2011uint16_t raw_data[4];2012memcpy(raw_data, dataptr, 2 * 4);2013c.r = Math::half_to_float(raw_data[0]);2014c.g = Math::half_to_float(raw_data[1]);2015c.b = Math::half_to_float(raw_data[2]);2016c.a = Math::half_to_float(raw_data[3]);2017}20182019return c;2020}20212022void MeshStorage::_multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_buffer) {2023MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);2024ERR_FAIL_NULL(multimesh);20252026// Assign data to previous buffer if motion vectors are used, that data will be made current in _update_dirty_multimeshes().2027bool uses_motion_vectors = RSG::viewport->get_num_viewports_with_motion_vectors() > 0;2028int buffer_index = uses_motion_vectors ? multimesh->prev_buffer : multimesh->current_buffer;20292030if (multimesh->uses_colors || multimesh->uses_custom_data) {2031// Color and custom need to be packed so copy buffer to data_cache and pack.20322033_multimesh_make_local(multimesh);20342035uint32_t old_stride = multimesh->xform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12;2036old_stride += multimesh->uses_colors ? 4 : 0;2037old_stride += multimesh->uses_custom_data ? 4 : 0;2038ERR_FAIL_COND(p_buffer.size() != (multimesh->instances * (int)old_stride));20392040multimesh->data_cache = p_buffer;20412042float *w = multimesh->data_cache.ptrw();20432044for (int i = 0; i < multimesh->instances; i++) {2045{2046float *dataptr = w + i * old_stride;2047float *newptr = w + i * multimesh->stride_cache;2048float vals[8] = { dataptr[0], dataptr[1], dataptr[2], dataptr[3], dataptr[4], dataptr[5], dataptr[6], dataptr[7] };2049memcpy(newptr, vals, 8 * 4);2050}20512052if (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_3D) {2053float *dataptr = w + i * old_stride + 8;2054float *newptr = w + i * multimesh->stride_cache + 8;2055float vals[8] = { dataptr[0], dataptr[1], dataptr[2], dataptr[3] };2056memcpy(newptr, vals, 4 * 4);2057}20582059if (multimesh->uses_colors) {2060float *dataptr = w + i * old_stride + (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12);2061float *newptr = w + i * multimesh->stride_cache + multimesh->color_offset_cache;2062uint16_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]) };2063memcpy(newptr, val, 2 * 4);2064}2065if (multimesh->uses_custom_data) {2066float *dataptr = w + i * old_stride + (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12) + (multimesh->uses_colors ? 4 : 0);2067float *newptr = w + i * multimesh->stride_cache + multimesh->custom_data_offset_cache;2068uint16_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]) };2069memcpy(newptr, val, 2 * 4);2070}2071}20722073multimesh->data_cache.resize(multimesh->instances * (int)multimesh->stride_cache);2074const float *r = multimesh->data_cache.ptr();2075glBindBuffer(GL_ARRAY_BUFFER, multimesh->buffer[buffer_index]);2076glBufferData(GL_ARRAY_BUFFER, multimesh->data_cache.size() * sizeof(float), r, GL_STATIC_DRAW);2077glBindBuffer(GL_ARRAY_BUFFER, 0);20782079} else {2080// If we have a data cache, just update it.2081if (multimesh->data_cache.size()) {2082multimesh->data_cache = p_buffer;2083}20842085// Only Transform is being used, so we can upload directly.2086ERR_FAIL_COND(p_buffer.size() != (multimesh->instances * (int)multimesh->stride_cache));2087const float *r = p_buffer.ptr();2088glBindBuffer(GL_ARRAY_BUFFER, multimesh->buffer[buffer_index]);2089glBufferData(GL_ARRAY_BUFFER, p_buffer.size() * sizeof(float), r, GL_STATIC_DRAW);2090glBindBuffer(GL_ARRAY_BUFFER, 0);2091}20922093multimesh->buffer_set = true;20942095if (multimesh->data_cache.size() || multimesh->uses_colors || multimesh->uses_custom_data) {2096// Clear dirty since nothing will be dirty anymore.2097uint32_t data_cache_dirty_region_count = Math::division_round_up(multimesh->instances, MULTIMESH_DIRTY_REGION_SIZE);2098for (uint32_t i = 0; i < data_cache_dirty_region_count; i++) {2099multimesh->data_cache_dirty_regions[i] = false;2100}2101multimesh->data_cache_used_dirty_regions = 0;21022103_multimesh_mark_all_dirty(multimesh, false, true); //update AABB2104} else if (multimesh->mesh.is_valid()) {2105//if we have a mesh set, we need to re-generate the AABB from the new data2106const float *data = p_buffer.ptr();21072108if (multimesh->custom_aabb == AABB()) {2109_multimesh_re_create_aabb(multimesh, data, multimesh->instances);2110multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);2111}2112}2113}21142115RID MeshStorage::_multimesh_get_command_buffer_rd_rid(RID p_multimesh) const {2116ERR_FAIL_V_MSG(RID(), "GLES3 does not implement indirect multimeshes.");2117}21182119RID MeshStorage::_multimesh_get_buffer_rd_rid(RID p_multimesh) const {2120ERR_FAIL_V_MSG(RID(), "GLES3 does not contain a Rid for the multimesh buffer.");2121}21222123Vector<float> MeshStorage::_multimesh_get_buffer(RID p_multimesh) const {2124MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);2125ERR_FAIL_NULL_V(multimesh, Vector<float>());2126Vector<float> ret;2127if (multimesh->buffer[multimesh->current_buffer] == 0 || multimesh->instances == 0) {2128return Vector<float>();2129} else if (multimesh->data_cache.size()) {2130ret = multimesh->data_cache;2131} else {2132// Buffer not cached, so fetch from GPU memory. This can be a stalling operation, avoid whenever possible.21332134Vector<uint8_t> buffer = Utilities::buffer_get_data(GL_ARRAY_BUFFER, multimesh->buffer[multimesh->current_buffer], multimesh->instances * multimesh->stride_cache * sizeof(float));2135ret.resize(multimesh->instances * multimesh->stride_cache);2136{2137float *w = ret.ptrw();2138const uint8_t *r = buffer.ptr();2139memcpy(w, r, buffer.size());2140}2141}2142if (multimesh->uses_colors || multimesh->uses_custom_data) {2143// Need to decompress buffer.2144uint32_t new_stride = multimesh->xform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12;2145new_stride += multimesh->uses_colors ? 4 : 0;2146new_stride += multimesh->uses_custom_data ? 4 : 0;21472148Vector<float> decompressed;2149decompressed.resize(multimesh->instances * (int)new_stride);2150float *w = decompressed.ptrw();2151const float *r = ret.ptr();21522153for (int i = 0; i < multimesh->instances; i++) {2154{2155float *newptr = w + i * new_stride;2156const float *oldptr = r + i * multimesh->stride_cache;2157float vals[8] = { oldptr[0], oldptr[1], oldptr[2], oldptr[3], oldptr[4], oldptr[5], oldptr[6], oldptr[7] };2158memcpy(newptr, vals, 8 * 4);2159}21602161if (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_3D) {2162float *newptr = w + i * new_stride + 8;2163const float *oldptr = r + i * multimesh->stride_cache + 8;2164float vals[8] = { oldptr[0], oldptr[1], oldptr[2], oldptr[3] };2165memcpy(newptr, vals, 4 * 4);2166}21672168if (multimesh->uses_colors) {2169float *newptr = w + i * new_stride + (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12);2170const float *oldptr = r + i * multimesh->stride_cache + multimesh->color_offset_cache;2171uint16_t raw_data[4];2172memcpy(raw_data, oldptr, 2 * 4);2173newptr[0] = Math::half_to_float(raw_data[0]);2174newptr[1] = Math::half_to_float(raw_data[1]);2175newptr[2] = Math::half_to_float(raw_data[2]);2176newptr[3] = Math::half_to_float(raw_data[3]);2177}2178if (multimesh->uses_custom_data) {2179float *newptr = w + i * new_stride + (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12) + (multimesh->uses_colors ? 4 : 0);2180const float *oldptr = r + i * multimesh->stride_cache + multimesh->custom_data_offset_cache;2181uint16_t raw_data[4];2182memcpy(raw_data, oldptr, 2 * 4);2183newptr[0] = Math::half_to_float(raw_data[0]);2184newptr[1] = Math::half_to_float(raw_data[1]);2185newptr[2] = Math::half_to_float(raw_data[2]);2186newptr[3] = Math::half_to_float(raw_data[3]);2187}2188}2189return decompressed;2190} else {2191return ret;2192}2193}21942195void MeshStorage::_multimesh_set_visible_instances(RID p_multimesh, int p_visible) {2196MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);2197ERR_FAIL_NULL(multimesh);2198ERR_FAIL_COND(p_visible < -1 || p_visible > multimesh->instances);2199if (multimesh->visible_instances == p_visible) {2200return;2201}22022203if (multimesh->data_cache.size()) {2204// There is a data cache, but we may need to update some sections.2205_multimesh_mark_all_dirty(multimesh, false, true);2206int start = multimesh->visible_instances >= 0 ? multimesh->visible_instances : multimesh->instances;2207for (int i = start; i < p_visible; i++) {2208_multimesh_mark_dirty(multimesh, i, true);2209}2210}22112212multimesh->visible_instances = p_visible;22132214multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES);2215}22162217int MeshStorage::_multimesh_get_visible_instances(RID p_multimesh) const {2218MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);2219ERR_FAIL_NULL_V(multimesh, 0);2220return multimesh->visible_instances;2221}22222223MeshStorage::MultiMeshInterpolator *MeshStorage::_multimesh_get_interpolator(RID p_multimesh) const {2224MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);2225ERR_FAIL_NULL_V_MSG(multimesh, nullptr, "Multimesh not found: " + itos(p_multimesh.get_id()));22262227return &multimesh->interpolator;2228}22292230void MeshStorage::_update_dirty_multimeshes() {2231while (multimesh_dirty_list) {2232MultiMesh *multimesh = multimesh_dirty_list;22332234bool uses_motion_vectors = RSG::viewport->get_num_viewports_with_motion_vectors() > 0;2235if (uses_motion_vectors) {2236multimesh->prev_buffer = multimesh->current_buffer;2237uint32_t new_buffer_index = multimesh->current_buffer ^ 1;22382239// Generate secondary buffer if it doesn't exist.2240if (multimesh->buffer[new_buffer_index] == 0 && multimesh->instances) {2241GLuint new_buffer = 0;2242glGenBuffers(1, &new_buffer);2243glBindBuffer(GL_ARRAY_BUFFER, new_buffer);2244GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, new_buffer, multimesh->instances * multimesh->stride_cache * sizeof(float), nullptr, GL_STATIC_DRAW, "MultiMesh secondary buffer");2245glBindBuffer(GL_ARRAY_BUFFER, 0);2246multimesh->buffer[new_buffer_index] = new_buffer;2247}22482249multimesh->current_buffer = new_buffer_index;2250multimesh->last_change = RSG::rasterizer->get_frame_number();2251}22522253_update_dirty_multimesh(multimesh, uses_motion_vectors);22542255multimesh_dirty_list = multimesh->dirty_list;22562257multimesh->dirty_list = nullptr;2258multimesh->dirty = false;2259}22602261multimesh_dirty_list = nullptr;2262}22632264void MeshStorage::_update_dirty_multimesh(MultiMesh *p_multimesh, bool p_uses_motion_vectors) {2265if (p_multimesh->data_cache.size()) { // May have been cleared, so only process if it exists.2266const float *data = p_multimesh->data_cache.ptr();22672268uint32_t visible_instances = p_multimesh->visible_instances >= 0 ? p_multimesh->visible_instances : p_multimesh->instances;22692270if (p_multimesh->data_cache_used_dirty_regions) {2271uint32_t data_cache_dirty_region_count = Math::division_round_up(p_multimesh->instances, (int)MULTIMESH_DIRTY_REGION_SIZE);2272uint32_t visible_region_count = visible_instances == 0 ? 0 : Math::division_round_up(visible_instances, (uint32_t)MULTIMESH_DIRTY_REGION_SIZE);22732274GLint region_size = p_multimesh->stride_cache * MULTIMESH_DIRTY_REGION_SIZE * sizeof(float);22752276if (p_multimesh->data_cache_used_dirty_regions > 32 || p_multimesh->data_cache_used_dirty_regions > visible_region_count / 2 || p_uses_motion_vectors) {2277// If there are too many dirty regions, the dirty regions represent the majority of visible regions, or motion vectors are used:2278// Just copy all, else transfer cost piles up too much.2279glBindBuffer(GL_ARRAY_BUFFER, p_multimesh->buffer[p_multimesh->current_buffer]);2280glBufferSubData(GL_ARRAY_BUFFER, 0, MIN(visible_region_count * region_size, p_multimesh->instances * p_multimesh->stride_cache * sizeof(float)), data);2281glBindBuffer(GL_ARRAY_BUFFER, 0);2282} else {2283// Not that many regions? Update them all.2284// TODO: profile the performance cost on low end2285glBindBuffer(GL_ARRAY_BUFFER, p_multimesh->buffer[p_multimesh->current_buffer]);2286for (uint32_t i = 0; i < visible_region_count; i++) {2287if (p_multimesh->data_cache_dirty_regions[i]) {2288GLint offset = i * region_size;2289GLint size = p_multimesh->stride_cache * (uint32_t)p_multimesh->instances * (uint32_t)sizeof(float);2290uint32_t region_start_index = p_multimesh->stride_cache * MULTIMESH_DIRTY_REGION_SIZE * i;2291glBufferSubData(GL_ARRAY_BUFFER, offset, MIN(region_size, size - offset), &data[region_start_index]);2292}2293}2294glBindBuffer(GL_ARRAY_BUFFER, 0);2295}22962297for (uint32_t i = 0; i < data_cache_dirty_region_count; i++) {2298p_multimesh->data_cache_dirty_regions[i] = false;2299}23002301p_multimesh->data_cache_used_dirty_regions = 0;2302}23032304if (p_multimesh->aabb_dirty && p_multimesh->mesh.is_valid()) {2305p_multimesh->aabb_dirty = false;2306if (p_multimesh->custom_aabb == AABB()) {2307_multimesh_re_create_aabb(p_multimesh, data, visible_instances);2308p_multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);2309}2310}2311}2312}23132314void GLES3::MeshStorage::multimesh_vertex_attrib_setup(GLuint p_instance_buffer, uint32_t p_stride, bool p_uses_format_2d, bool p_has_color_or_custom_data, int p_attrib_base_index) {2315glBindBuffer(GL_ARRAY_BUFFER, p_instance_buffer);23162317glEnableVertexAttribArray(p_attrib_base_index + 0);2318glVertexAttribPointer(p_attrib_base_index + 0, 4, GL_FLOAT, GL_FALSE, p_stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(0));2319glVertexAttribDivisor(p_attrib_base_index + 0, 1);2320glEnableVertexAttribArray(p_attrib_base_index + 1);2321glVertexAttribPointer(p_attrib_base_index + 1, 4, GL_FLOAT, GL_FALSE, p_stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(sizeof(float) * 4));2322glVertexAttribDivisor(p_attrib_base_index + 1, 1);2323if (!p_uses_format_2d) {2324glEnableVertexAttribArray(p_attrib_base_index + 2);2325glVertexAttribPointer(p_attrib_base_index + 2, 4, GL_FLOAT, GL_FALSE, p_stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(sizeof(float) * 8));2326glVertexAttribDivisor(p_attrib_base_index + 2, 1);2327}23282329if (p_has_color_or_custom_data) {2330uint32_t color_custom_offset = p_uses_format_2d ? 8 : 12;2331glEnableVertexAttribArray(p_attrib_base_index + 3);2332glVertexAttribIPointer(p_attrib_base_index + 3, 4, GL_UNSIGNED_INT, p_stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(color_custom_offset * sizeof(float)));2333glVertexAttribDivisor(p_attrib_base_index + 3, 1);2334} else {2335// Set all default instance color and custom data values to 1.0 or 0.0 using a compressed format.2336uint16_t zero = Math::make_half_float(0.0f);2337uint16_t one = Math::make_half_float(1.0f);2338GLuint default_color = (uint32_t(one) << 16) | one;2339GLuint default_custom = (uint32_t(zero) << 16) | zero;2340glVertexAttribI4ui(p_attrib_base_index + 3, default_color, default_color, default_custom, default_custom);2341}2342}23432344/* SKELETON API */23452346RID MeshStorage::skeleton_allocate() {2347return skeleton_owner.allocate_rid();2348}23492350void MeshStorage::skeleton_initialize(RID p_rid) {2351skeleton_owner.initialize_rid(p_rid, Skeleton());2352}23532354void MeshStorage::skeleton_free(RID p_rid) {2355_update_dirty_skeletons();2356skeleton_allocate_data(p_rid, 0);2357Skeleton *skeleton = skeleton_owner.get_or_null(p_rid);2358skeleton->dependency.deleted_notify(p_rid);2359skeleton_owner.free(p_rid);2360}23612362void MeshStorage::_skeleton_make_dirty(Skeleton *skeleton) {2363if (!skeleton->dirty) {2364skeleton->dirty = true;2365skeleton->dirty_list = skeleton_dirty_list;2366skeleton_dirty_list = skeleton;2367}2368}23692370void MeshStorage::skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton) {2371Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);2372ERR_FAIL_NULL(skeleton);2373ERR_FAIL_COND(p_bones < 0);23742375if (skeleton->size == p_bones && skeleton->use_2d == p_2d_skeleton) {2376return;2377}23782379skeleton->size = p_bones;2380skeleton->use_2d = p_2d_skeleton;2381skeleton->height = (p_bones * (p_2d_skeleton ? 2 : 3)) / 256;2382if ((p_bones * (p_2d_skeleton ? 2 : 3)) % 256) {2383skeleton->height++;2384}23852386if (skeleton->transforms_texture != 0) {2387GLES3::Utilities::get_singleton()->texture_free_data(skeleton->transforms_texture);2388skeleton->transforms_texture = 0;2389skeleton->data.clear();2390}23912392if (skeleton->size) {2393skeleton->data.resize(256 * skeleton->height * 4);2394glGenTextures(1, &skeleton->transforms_texture);2395glBindTexture(GL_TEXTURE_2D, skeleton->transforms_texture);2396glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 256, skeleton->height, 0, GL_RGBA, GL_FLOAT, nullptr);2397glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);2398glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);2399glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);2400glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);2401glBindTexture(GL_TEXTURE_2D, 0);2402GLES3::Utilities::get_singleton()->texture_allocated_data(skeleton->transforms_texture, skeleton->data.size() * sizeof(float), "Skeleton transforms texture");24032404memset(skeleton->data.ptr(), 0, skeleton->data.size() * sizeof(float));24052406_skeleton_make_dirty(skeleton);2407}24082409skeleton->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_SKELETON_DATA);2410}24112412void MeshStorage::skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) {2413Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);24142415ERR_FAIL_NULL(skeleton);2416ERR_FAIL_COND(!skeleton->use_2d);24172418skeleton->base_transform_2d = p_base_transform;2419}24202421int MeshStorage::skeleton_get_bone_count(RID p_skeleton) const {2422Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);2423ERR_FAIL_NULL_V(skeleton, 0);24242425return skeleton->size;2426}24272428void MeshStorage::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform3D &p_transform) {2429Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);24302431ERR_FAIL_NULL(skeleton);2432ERR_FAIL_INDEX(p_bone, skeleton->size);2433ERR_FAIL_COND(skeleton->use_2d);24342435float *dataptr = skeleton->data.ptr() + p_bone * 12;24362437dataptr[0] = p_transform.basis.rows[0][0];2438dataptr[1] = p_transform.basis.rows[0][1];2439dataptr[2] = p_transform.basis.rows[0][2];2440dataptr[3] = p_transform.origin.x;2441dataptr[4] = p_transform.basis.rows[1][0];2442dataptr[5] = p_transform.basis.rows[1][1];2443dataptr[6] = p_transform.basis.rows[1][2];2444dataptr[7] = p_transform.origin.y;2445dataptr[8] = p_transform.basis.rows[2][0];2446dataptr[9] = p_transform.basis.rows[2][1];2447dataptr[10] = p_transform.basis.rows[2][2];2448dataptr[11] = p_transform.origin.z;24492450_skeleton_make_dirty(skeleton);2451}24522453Transform3D MeshStorage::skeleton_bone_get_transform(RID p_skeleton, int p_bone) const {2454Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);24552456ERR_FAIL_NULL_V(skeleton, Transform3D());2457ERR_FAIL_INDEX_V(p_bone, skeleton->size, Transform3D());2458ERR_FAIL_COND_V(skeleton->use_2d, Transform3D());24592460const float *dataptr = skeleton->data.ptr() + p_bone * 12;24612462Transform3D t;24632464t.basis.rows[0][0] = dataptr[0];2465t.basis.rows[0][1] = dataptr[1];2466t.basis.rows[0][2] = dataptr[2];2467t.origin.x = dataptr[3];2468t.basis.rows[1][0] = dataptr[4];2469t.basis.rows[1][1] = dataptr[5];2470t.basis.rows[1][2] = dataptr[6];2471t.origin.y = dataptr[7];2472t.basis.rows[2][0] = dataptr[8];2473t.basis.rows[2][1] = dataptr[9];2474t.basis.rows[2][2] = dataptr[10];2475t.origin.z = dataptr[11];24762477return t;2478}24792480void MeshStorage::skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) {2481Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);24822483ERR_FAIL_NULL(skeleton);2484ERR_FAIL_INDEX(p_bone, skeleton->size);2485ERR_FAIL_COND(!skeleton->use_2d);24862487float *dataptr = skeleton->data.ptr() + p_bone * 8;24882489dataptr[0] = p_transform.columns[0][0];2490dataptr[1] = p_transform.columns[1][0];2491dataptr[2] = 0;2492dataptr[3] = p_transform.columns[2][0];2493dataptr[4] = p_transform.columns[0][1];2494dataptr[5] = p_transform.columns[1][1];2495dataptr[6] = 0;2496dataptr[7] = p_transform.columns[2][1];24972498_skeleton_make_dirty(skeleton);2499}25002501Transform2D MeshStorage::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const {2502Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);25032504ERR_FAIL_NULL_V(skeleton, Transform2D());2505ERR_FAIL_INDEX_V(p_bone, skeleton->size, Transform2D());2506ERR_FAIL_COND_V(!skeleton->use_2d, Transform2D());25072508const float *dataptr = skeleton->data.ptr() + p_bone * 8;25092510Transform2D t;2511t.columns[0][0] = dataptr[0];2512t.columns[1][0] = dataptr[1];2513t.columns[2][0] = dataptr[3];2514t.columns[0][1] = dataptr[4];2515t.columns[1][1] = dataptr[5];2516t.columns[2][1] = dataptr[7];25172518return t;2519}25202521void MeshStorage::_update_dirty_skeletons() {2522while (skeleton_dirty_list) {2523Skeleton *skeleton = skeleton_dirty_list;25242525if (skeleton->size) {2526glBindTexture(GL_TEXTURE_2D, skeleton->transforms_texture);2527glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 256, skeleton->height, 0, GL_RGBA, GL_FLOAT, skeleton->data.ptr());2528glBindTexture(GL_TEXTURE_2D, 0);2529}25302531skeleton_dirty_list = skeleton->dirty_list;25322533skeleton->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_SKELETON_BONES);25342535skeleton->version++;25362537skeleton->dirty = false;2538skeleton->dirty_list = nullptr;2539}25402541skeleton_dirty_list = nullptr;2542}25432544void MeshStorage::skeleton_update_dependency(RID p_skeleton, DependencyTracker *p_instance) {2545Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);2546ERR_FAIL_NULL(skeleton);25472548p_instance->update_dependency(&skeleton->dependency);2549}25502551#endif // GLES3_ENABLED255225532554