From a63028e1728e76f8b019e2038e0235cf9d168f5d Mon Sep 17 00:00:00 2001 From: Omar El Sheikh Date: Mon, 16 Aug 2021 20:41:43 -0400 Subject: [PATCH] Fix Octahedral/Split Stream Options Update mesh_surface_get_format_stride and mesh_surface_make_offsets_from_format to return an array of offsets and an array of strides in order to support vertex stream splitting Update _get_array_from_surface to also support vertex stream splitting Add a condition on split stream usage to ensure it does not get used on dynamic meshes Handle case when Tangent is compressed but Normal is not compressed Make stream splitting option require a restart in the settings Update SoftBody and Sprite3D to support and use strides and offsets returned by updated visual_server functions Update Sprite3D to use the dynamic mesh flag --- doc/classes/VisualServer.xml | 2 +- drivers/gles2/rasterizer_storage_gles2.cpp | 6 +- drivers/gles3/rasterizer_storage_gles3.cpp | 4 +- scene/3d/mesh_instance.cpp | 10 +- scene/3d/soft_body.cpp | 5 +- scene/3d/sprite_3d.cpp | 26 ++-- scene/3d/sprite_3d.h | 2 +- servers/visual_server.cpp | 158 +++++++++++++++------ servers/visual_server.h | 4 +- 9 files changed, 150 insertions(+), 67 deletions(-) diff --git a/doc/classes/VisualServer.xml b/doc/classes/VisualServer.xml index ae7308c860b..e762d30b794 100644 --- a/doc/classes/VisualServer.xml +++ b/doc/classes/VisualServer.xml @@ -1958,8 +1958,8 @@ + - Function is unused in Godot 3.x. diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index 6f898b32358..4d2d8cf2b03 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -2114,7 +2114,7 @@ static PoolVector _unpack_half_floats(const PoolVector &array, } break; case VS::ARRAY_TANGENT: { if (p_format & VS::ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) { - if (!(p_format & VS::ARRAY_COMPRESS_TANGENT)) { + if (!(p_format & VS::ARRAY_COMPRESS_TANGENT && p_format & VS::ARRAY_COMPRESS_NORMAL)) { src_size[VS::ARRAY_NORMAL] = 8; dst_size[VS::ARRAY_NORMAL] = 8; } @@ -2254,7 +2254,7 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, VS: } //bool has_morph = p_blend_shapes.size(); - bool use_split_stream = GLOBAL_GET("rendering/mesh_storage/split_stream"); + bool use_split_stream = GLOBAL_GET("rendering/mesh_storage/split_stream") && !(p_format & VS::ARRAY_FLAG_USE_DYNAMIC_UPDATE); Surface::Attrib attribs[VS::ARRAY_MAX]; @@ -2330,7 +2330,7 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, VS: case VS::ARRAY_TANGENT: { if (p_format & VS::ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) { attribs[i].enabled = false; - if (p_format & VS::ARRAY_COMPRESS_TANGENT) { + if (p_format & VS::ARRAY_COMPRESS_TANGENT && p_format & VS::ARRAY_COMPRESS_NORMAL) { // normal and tangent will each be oct16 (2 bytes each) // pack into single vec4 for memory bandwidth // savings while keeping 4 byte alignment diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index c9c8906b850..15c1cc3fc70 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -3349,7 +3349,7 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS: } //bool has_morph = p_blend_shapes.size(); - bool use_split_stream = GLOBAL_GET("rendering/mesh_storage/split_stream"); + bool use_split_stream = GLOBAL_GET("rendering/mesh_storage/split_stream") && !(p_format & VS::ARRAY_FLAG_USE_DYNAMIC_UPDATE); Surface::Attrib attribs[VS::ARRAY_MAX]; @@ -3424,7 +3424,7 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS: case VS::ARRAY_TANGENT: { if (p_format & VS::ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) { attribs[i].enabled = false; - if (p_format & VS::ARRAY_COMPRESS_TANGENT) { + if (p_format & VS::ARRAY_COMPRESS_TANGENT && p_format & VS::ARRAY_COMPRESS_NORMAL) { // normal and tangent will each be oct16 (2 bytes each) // pack into single vec4 for memory bandwidth // savings while keeping 4 byte alignment diff --git a/scene/3d/mesh_instance.cpp b/scene/3d/mesh_instance.cpp index 38fb11d2409..c7962909f49 100644 --- a/scene/3d/mesh_instance.cpp +++ b/scene/3d/mesh_instance.cpp @@ -414,7 +414,10 @@ void MeshInstance::_update_skinning() { const int index_count_write = software_skinning_mesh->surface_get_array_index_len(surface_index); uint32_t array_offsets_write[Mesh::ARRAY_MAX]; - const uint32_t stride_write = visual_server->mesh_surface_make_offsets_from_format(format_write, vertex_count_write, index_count_write, array_offsets_write); + uint32_t array_strides_write[Mesh::ARRAY_MAX]; + visual_server->mesh_surface_make_offsets_from_format(format_write, vertex_count_write, index_count_write, array_offsets_write, array_strides_write); + ERR_FAIL_COND(array_strides_write[Mesh::ARRAY_VERTEX] != array_strides_write[Mesh::ARRAY_NORMAL]) + const uint32_t stride_write = array_strides_write[Mesh::ARRAY_VERTEX]; const uint32_t offset_vertices_write = array_offsets_write[Mesh::ARRAY_VERTEX]; const uint32_t offset_normals_write = array_offsets_write[Mesh::ARRAY_NORMAL]; const uint32_t offset_tangents_write = array_offsets_write[Mesh::ARRAY_TANGENT]; @@ -433,7 +436,10 @@ void MeshInstance::_update_skinning() { ERR_CONTINUE(vertex_count != vertex_count_write); uint32_t array_offsets[Mesh::ARRAY_MAX]; - const uint32_t stride = visual_server->mesh_surface_make_offsets_from_format(format_read, vertex_count, index_count, array_offsets); + uint32_t array_strides[Mesh::ARRAY_MAX]; + visual_server->mesh_surface_make_offsets_from_format(format_read, vertex_count, index_count, array_offsets, array_strides); + ERR_FAIL_COND(array_strides[Mesh::ARRAY_VERTEX] != array_strides[Mesh::ARRAY_NORMAL]) + const uint32_t stride = array_strides[Mesh::ARRAY_VERTEX]; const uint32_t offset_vertices = array_offsets[Mesh::ARRAY_VERTEX]; const uint32_t offset_normals = array_offsets[Mesh::ARRAY_NORMAL]; const uint32_t offset_tangents = array_offsets[Mesh::ARRAY_TANGENT]; diff --git a/scene/3d/soft_body.cpp b/scene/3d/soft_body.cpp index ede29ecad0d..78a6ef2c817 100644 --- a/scene/3d/soft_body.cpp +++ b/scene/3d/soft_body.cpp @@ -52,9 +52,12 @@ void SoftBodyVisualServerHandler::prepare(RID p_mesh, int p_surface) { const int surface_vertex_len = VS::get_singleton()->mesh_surface_get_array_len(mesh, p_surface); const int surface_index_len = VS::get_singleton()->mesh_surface_get_array_index_len(mesh, p_surface); uint32_t surface_offsets[VS::ARRAY_MAX]; + uint32_t surface_strides[VS::ARRAY_MAX]; buffer = VS::get_singleton()->mesh_surface_get_array(mesh, surface); - stride = VS::get_singleton()->mesh_surface_make_offsets_from_format(surface_format, surface_vertex_len, surface_index_len, surface_offsets); + VS::get_singleton()->mesh_surface_make_offsets_from_format(surface_format, surface_vertex_len, surface_index_len, surface_offsets, surface_strides); + ERR_FAIL_COND(surface_strides[VS::ARRAY_VERTEX] != surface_strides[VS::ARRAY_NORMAL]); + stride = surface_strides[VS::ARRAY_VERTEX]; offset_vertices = surface_offsets[VS::ARRAY_VERTEX]; offset_normal = surface_offsets[VS::ARRAY_NORMAL]; } diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 3cc9b1e6e88..22f4aed99b7 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -404,13 +404,15 @@ SpriteBase3D::SpriteBase3D() { mesh_array[VS::ARRAY_COLOR] = mesh_colors; mesh_array[VS::ARRAY_TEX_UV] = mesh_uvs; - VS::get_singleton()->mesh_add_surface_from_arrays(mesh, VS::PRIMITIVE_TRIANGLE_FAN, mesh_array, Array(), (VS::ARRAY_COMPRESS_DEFAULT & ~VS::ARRAY_COMPRESS_TEX_UV) & ~VS::ARRAY_COMPRESS_COLOR); + uint32_t compress_format = (VS::ARRAY_COMPRESS_DEFAULT & ~VS::ARRAY_COMPRESS_TEX_UV) & ~VS::ARRAY_COMPRESS_COLOR; + compress_format |= VS::ARRAY_FLAG_USE_DYNAMIC_UPDATE; + VS::get_singleton()->mesh_add_surface_from_arrays(mesh, VS::PRIMITIVE_TRIANGLE_FAN, mesh_array, Array(), compress_format); const int surface_vertex_len = VS::get_singleton()->mesh_surface_get_array_len(mesh, 0); const int surface_index_len = VS::get_singleton()->mesh_surface_get_array_index_len(mesh, 0); mesh_surface_format = VS::get_singleton()->mesh_surface_get_format(mesh, 0); mesh_buffer = VS::get_singleton()->mesh_surface_get_array(mesh, 0); - mesh_stride = VS::get_singleton()->mesh_surface_make_offsets_from_format(mesh_surface_format, surface_vertex_len, surface_index_len, mesh_surface_offsets); + VS::get_singleton()->mesh_surface_make_offsets_from_format(mesh_surface_format, surface_vertex_len, surface_index_len, mesh_surface_offsets, mesh_stride); set_base(mesh); } @@ -558,13 +560,13 @@ void Sprite3D::_draw() { } float v_uv[2] = { uvs[i].x, uvs[i].y }; - memcpy(&write_buffer[i * mesh_stride + mesh_surface_offsets[VS::ARRAY_TEX_UV]], v_uv, 8); + memcpy(&write_buffer[i * mesh_stride[VS::ARRAY_TEX_UV] + mesh_surface_offsets[VS::ARRAY_TEX_UV]], v_uv, 8); float v_vertex[3] = { vtx.x, vtx.y, vtx.z }; - memcpy(&write_buffer[i * mesh_stride + mesh_surface_offsets[VS::ARRAY_VERTEX]], &v_vertex, sizeof(float) * 3); - memcpy(&write_buffer[i * mesh_stride + mesh_surface_offsets[VS::ARRAY_NORMAL]], v_normal, 2); - memcpy(&write_buffer[i * mesh_stride + mesh_surface_offsets[VS::ARRAY_TANGENT]], v_tangent, 2); - memcpy(&write_buffer[i * mesh_stride + mesh_surface_offsets[VS::ARRAY_COLOR]], color.components, 4 * 4); + memcpy(&write_buffer[i * mesh_stride[VS::ARRAY_VERTEX] + mesh_surface_offsets[VS::ARRAY_VERTEX]], &v_vertex, sizeof(float) * 3); + memcpy(&write_buffer[i * mesh_stride[VS::ARRAY_NORMAL] + mesh_surface_offsets[VS::ARRAY_NORMAL]], v_normal, 2); + memcpy(&write_buffer[i * mesh_stride[VS::ARRAY_TANGENT] + mesh_surface_offsets[VS::ARRAY_TANGENT]], v_tangent, 2); + memcpy(&write_buffer[i * mesh_stride[VS::ARRAY_COLOR] + mesh_surface_offsets[VS::ARRAY_COLOR]], color.components, 4 * 4); } write_buffer.release(); @@ -903,13 +905,13 @@ void AnimatedSprite3D::_draw() { } float v_uv[2] = { uvs[i].x, uvs[i].y }; - memcpy(&write_buffer[i * mesh_stride + mesh_surface_offsets[VS::ARRAY_TEX_UV]], v_uv, 8); + memcpy(&write_buffer[i * mesh_stride[VS::ARRAY_TEX_UV] + mesh_surface_offsets[VS::ARRAY_TEX_UV]], v_uv, 8); float v_vertex[3] = { vtx.x, vtx.y, vtx.z }; - memcpy(&write_buffer[i * mesh_stride + mesh_surface_offsets[VS::ARRAY_VERTEX]], &v_vertex, sizeof(float) * 3); - memcpy(&write_buffer[i * mesh_stride + mesh_surface_offsets[VS::ARRAY_NORMAL]], v_normal, 2); - memcpy(&write_buffer[i * mesh_stride + mesh_surface_offsets[VS::ARRAY_TANGENT]], v_tangent, 2); - memcpy(&write_buffer[i * mesh_stride + mesh_surface_offsets[VS::ARRAY_COLOR]], color.components, 4 * 4); + memcpy(&write_buffer[i * mesh_stride[VS::ARRAY_VERTEX] + mesh_surface_offsets[VS::ARRAY_VERTEX]], &v_vertex, sizeof(float) * 3); + memcpy(&write_buffer[i * mesh_stride[VS::ARRAY_NORMAL] + mesh_surface_offsets[VS::ARRAY_NORMAL]], v_normal, 2); + memcpy(&write_buffer[i * mesh_stride[VS::ARRAY_TANGENT] + mesh_surface_offsets[VS::ARRAY_TANGENT]], v_tangent, 2); + memcpy(&write_buffer[i * mesh_stride[VS::ARRAY_COLOR] + mesh_surface_offsets[VS::ARRAY_COLOR]], color.components, 4 * 4); } write_buffer.release(); diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h index 55822852676..c7955004b92 100644 --- a/scene/3d/sprite_3d.h +++ b/scene/3d/sprite_3d.h @@ -97,7 +97,7 @@ protected: uint32_t mesh_surface_offsets[VS::ARRAY_MAX]; PoolByteArray mesh_buffer; - uint32_t mesh_stride; + uint32_t mesh_stride[VS::ARRAY_MAX]; uint32_t mesh_surface_format; void _queue_update(); diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index 7f7a48825d6..eaf92c8a5cd 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -844,17 +844,24 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_ uint32_t VisualServer::mesh_surface_get_format_offset(uint32_t p_format, int p_vertex_len, int p_index_len, int p_array_index) const { uint32_t offsets[ARRAY_MAX]; - mesh_surface_make_offsets_from_format(p_format, p_vertex_len, p_index_len, offsets); + uint32_t strides[ARRAY_MAX]; + mesh_surface_make_offsets_from_format(p_format, p_vertex_len, p_index_len, offsets, strides); return offsets[p_array_index]; } -uint32_t VisualServer::mesh_surface_get_format_stride(uint32_t p_format, int p_vertex_len, int p_index_len) const { +uint32_t VisualServer::mesh_surface_get_format_stride(uint32_t p_format, int p_vertex_len, int p_index_len, int p_array_index) const { uint32_t offsets[ARRAY_MAX]; - return mesh_surface_make_offsets_from_format(p_format, p_vertex_len, p_index_len, offsets); + uint32_t strides[ARRAY_MAX]; + mesh_surface_make_offsets_from_format(p_format, p_vertex_len, p_index_len, offsets, strides); + return strides[p_array_index]; } -uint32_t VisualServer::mesh_surface_make_offsets_from_format(uint32_t p_format, int p_vertex_len, int p_index_len, uint32_t *r_offsets) const { - int total_elem_size = 0; +void VisualServer::mesh_surface_make_offsets_from_format(uint32_t p_format, int p_vertex_len, int p_index_len, uint32_t *r_offsets, uint32_t *r_strides) const { + bool use_split_stream = GLOBAL_GET("rendering/mesh_storage/split_stream") && !(p_format & VS::ARRAY_FLAG_USE_DYNAMIC_UPDATE); + + int attributes_base_offset = 0; + int attributes_stride = 0; + int positions_stride = 0; for (int i = 0; i < VS::ARRAY_MAX; i++) { r_offsets[i] = 0; //reset @@ -883,6 +890,14 @@ uint32_t VisualServer::mesh_surface_make_offsets_from_format(uint32_t p_format, elem_size = 8; } + r_offsets[i] = 0; + positions_stride = elem_size; + if (use_split_stream) { + attributes_base_offset = elem_size * p_vertex_len; + } else { + attributes_base_offset = elem_size; + } + } break; case VS::ARRAY_NORMAL: { if (p_format & ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) { @@ -901,12 +916,14 @@ uint32_t VisualServer::mesh_surface_make_offsets_from_format(uint32_t p_format, elem_size = sizeof(float) * 3; } } + r_offsets[i] = attributes_base_offset + attributes_stride; + attributes_stride += elem_size; } break; case VS::ARRAY_TANGENT: { if (p_format & ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) { - if (p_format & ARRAY_COMPRESS_TANGENT) { + if (p_format & ARRAY_COMPRESS_TANGENT && (p_format & ARRAY_FORMAT_NORMAL) && (p_format & ARRAY_COMPRESS_NORMAL)) { elem_size = sizeof(uint8_t) * 2; } else { elem_size = sizeof(uint16_t) * 2; @@ -918,6 +935,8 @@ uint32_t VisualServer::mesh_surface_make_offsets_from_format(uint32_t p_format, elem_size = sizeof(float) * 4; } } + r_offsets[i] = attributes_base_offset + attributes_stride; + attributes_stride += elem_size; } break; case VS::ARRAY_COLOR: { @@ -926,6 +945,9 @@ uint32_t VisualServer::mesh_surface_make_offsets_from_format(uint32_t p_format, } else { elem_size = sizeof(float) * 4; } + r_offsets[i] = attributes_base_offset + attributes_stride; + attributes_stride += elem_size; + } break; case VS::ARRAY_TEX_UV: { if (p_format & ARRAY_COMPRESS_TEX_UV) { @@ -933,6 +955,8 @@ uint32_t VisualServer::mesh_surface_make_offsets_from_format(uint32_t p_format, } else { elem_size = sizeof(float) * 2; } + r_offsets[i] = attributes_base_offset + attributes_stride; + attributes_stride += elem_size; } break; @@ -942,6 +966,8 @@ uint32_t VisualServer::mesh_surface_make_offsets_from_format(uint32_t p_format, } else { elem_size = sizeof(float) * 2; } + r_offsets[i] = attributes_base_offset + attributes_stride; + attributes_stride += elem_size; } break; case VS::ARRAY_WEIGHTS: { @@ -950,6 +976,8 @@ uint32_t VisualServer::mesh_surface_make_offsets_from_format(uint32_t p_format, } else { elem_size = sizeof(float) * 4; } + r_offsets[i] = attributes_base_offset + attributes_stride; + attributes_stride += elem_size; } break; case VS::ARRAY_BONES: { @@ -958,6 +986,8 @@ uint32_t VisualServer::mesh_surface_make_offsets_from_format(uint32_t p_format, } else { elem_size = sizeof(uint32_t); } + r_offsets[i] = attributes_base_offset + attributes_stride; + attributes_stride += elem_size; } break; case VS::ARRAY_INDEX: { @@ -976,21 +1006,28 @@ uint32_t VisualServer::mesh_surface_make_offsets_from_format(uint32_t p_format, continue; } default: { - ERR_FAIL_V(0); + ERR_FAIL(); } } - - r_offsets[i] = total_elem_size; - total_elem_size += elem_size; } - return total_elem_size; + + if (use_split_stream) { + r_strides[VS::ARRAY_VERTEX] = positions_stride; + for (int i = 1; i < VS::ARRAY_MAX - 1; i++) { + r_strides[i] = attributes_stride; + } + } else { + for (int i = 0; i < VS::ARRAY_MAX - 1; i++) { + r_strides[i] = positions_stride + attributes_stride; + } + } } void VisualServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, uint32_t p_compress_format) { ERR_FAIL_INDEX(p_primitive, VS::PRIMITIVE_MAX); ERR_FAIL_COND(p_arrays.size() != VS::ARRAY_MAX); - bool use_split_stream = GLOBAL_GET("rendering/mesh_storage/split_stream"); + bool use_split_stream = GLOBAL_GET("rendering/mesh_storage/split_stream") && !(p_compress_format & VS::ARRAY_FLAG_USE_DYNAMIC_UPDATE); uint32_t format = 0; @@ -1116,7 +1153,7 @@ void VisualServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_prim case VS::ARRAY_TANGENT: { if (p_compress_format & ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) { - if (p_compress_format & ARRAY_COMPRESS_TANGENT) { + if (p_compress_format & ARRAY_COMPRESS_TANGENT && (format & ARRAY_FORMAT_NORMAL) && (p_compress_format & ARRAY_COMPRESS_NORMAL)) { elem_size = sizeof(uint8_t) * 2; } else { elem_size = sizeof(uint16_t) * 2; @@ -1266,9 +1303,14 @@ void VisualServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_prim } Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector p_vertex_data, int p_vertex_len, PoolVector p_index_data, int p_index_len) const { - uint32_t offsets[ARRAY_MAX]; + bool use_split_stream = GLOBAL_GET("rendering/mesh_storage/split_stream") && !(p_format & VS::ARRAY_FLAG_USE_DYNAMIC_UPDATE); - int total_elem_size = 0; + uint32_t offsets[ARRAY_MAX]; + uint32_t strides[VS::ARRAY_MAX]; + + int attributes_base_offset = 0; + int attributes_stride = 0; + int positions_stride = 0; for (int i = 0; i < VS::ARRAY_MAX; i++) { offsets[i] = 0; //reset @@ -1278,7 +1320,6 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector::Write w = arr_2d.write(); for (int j = 0; j < p_vertex_len; j++) { - const uint16_t *v = (const uint16_t *)&r[j * total_elem_size + offsets[i]]; + const uint16_t *v = (const uint16_t *)&r[j * strides[i] + offsets[i]]; w[j] = Vector2(Math::halfptr_to_float(&v[0]), Math::halfptr_to_float(&v[1])); } } else { PoolVector::Write w = arr_2d.write(); for (int j = 0; j < p_vertex_len; j++) { - const float *v = (const float *)&r[j * total_elem_size + offsets[i]]; + const float *v = (const float *)&r[j * strides[i] + offsets[i]]; w[j] = Vector2(v[0], v[1]); } } @@ -1439,14 +1511,14 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector::Write w = arr_3d.write(); for (int j = 0; j < p_vertex_len; j++) { - const uint16_t *v = (const uint16_t *)&r[j * total_elem_size + offsets[i]]; + const uint16_t *v = (const uint16_t *)&r[j * strides[i] + offsets[i]]; w[j] = Vector3(Math::halfptr_to_float(&v[0]), Math::halfptr_to_float(&v[1]), Math::halfptr_to_float(&v[2])); } } else { PoolVector::Write w = arr_3d.write(); for (int j = 0; j < p_vertex_len; j++) { - const float *v = (const float *)&r[j * total_elem_size + offsets[i]]; + const float *v = (const float *)&r[j * strides[i] + offsets[i]]; w[j] = Vector3(v[0], v[1], v[2]); } } @@ -1464,7 +1536,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector::Write w = arr.write(); for (int j = 0; j < p_vertex_len; j++) { - const int8_t *n = (const int8_t *)&r[j * total_elem_size + offsets[i]]; + const int8_t *n = (const int8_t *)&r[j * strides[i] + offsets[i]]; Vector2 enc(n[0] / 127.0f, n[1] / 127.0f); w[j] = oct_to_norm(enc); @@ -1473,7 +1545,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector::Write w = arr.write(); for (int j = 0; j < p_vertex_len; j++) { - const int16_t *n = (const int16_t *)&r[j * total_elem_size + offsets[i]]; + const int16_t *n = (const int16_t *)&r[j * strides[i] + offsets[i]]; Vector2 enc(n[0] / 32767.0f, n[1] / 32767.0f); w[j] = oct_to_norm(enc); @@ -1485,14 +1557,14 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector::Write w = arr.write(); for (int j = 0; j < p_vertex_len; j++) { - const float *v = (const float *)&r[j * total_elem_size + offsets[i]]; + const float *v = (const float *)&r[j * strides[i] + offsets[i]]; w[j] = Vector3(v[0], v[1], v[2]); } } @@ -1511,7 +1583,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector::Write w = arr.write(); for (int j = 0; j < p_vertex_len; j++) { - const int8_t *t = (const int8_t *)&r[j * total_elem_size + offsets[i]]; + const int8_t *t = (const int8_t *)&r[j * strides[i] + offsets[i]]; Vector2 enc(t[0] / 127.0f, t[1] / 127.0f); Vector3 dec = oct_to_tangent(enc, &w[j * 4 + 3]); @@ -1523,7 +1595,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector::Write w = arr.write(); for (int j = 0; j < p_vertex_len; j++) { - const int16_t *t = (const int16_t *)&r[j * total_elem_size + offsets[i]]; + const int16_t *t = (const int16_t *)&r[j * strides[i] + offsets[i]]; Vector2 enc(t[0] / 32767.0f, t[1] / 32767.0f); Vector3 dec = oct_to_tangent(enc, &w[j * 4 + 3]); @@ -1537,7 +1609,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector::Write w = arr.write(); for (int j = 0; j < p_vertex_len; j++) { - const int8_t *v = (const int8_t *)&r[j * total_elem_size + offsets[i]]; + const int8_t *v = (const int8_t *)&r[j * strides[i] + offsets[i]]; for (int k = 0; k < 4; k++) { w[j * 4 + k] = float(v[k] / 127.0); } @@ -1546,7 +1618,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector::Write w = arr.write(); for (int j = 0; j < p_vertex_len; j++) { - const float *v = (const float *)&r[j * total_elem_size + offsets[i]]; + const float *v = (const float *)&r[j * strides[i] + offsets[i]]; for (int k = 0; k < 4; k++) { w[j * 4 + k] = v[k]; } @@ -1565,14 +1637,14 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector::Write w = arr.write(); for (int j = 0; j < p_vertex_len; j++) { - const uint8_t *v = (const uint8_t *)&r[j * total_elem_size + offsets[i]]; + const uint8_t *v = (const uint8_t *)&r[j * strides[i] + offsets[i]]; w[j] = Color(float(v[0] / 255.0), float(v[1] / 255.0), float(v[2] / 255.0), float(v[3] / 255.0)); } } else { PoolVector::Write w = arr.write(); for (int j = 0; j < p_vertex_len; j++) { - const float *v = (const float *)&r[j * total_elem_size + offsets[i]]; + const float *v = (const float *)&r[j * strides[i] + offsets[i]]; w[j] = Color(v[0], v[1], v[2], v[3]); } } @@ -1587,14 +1659,14 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector::Write w = arr.write(); for (int j = 0; j < p_vertex_len; j++) { - const uint16_t *v = (const uint16_t *)&r[j * total_elem_size + offsets[i]]; + const uint16_t *v = (const uint16_t *)&r[j * strides[i] + offsets[i]]; w[j] = Vector2(Math::halfptr_to_float(&v[0]), Math::halfptr_to_float(&v[1])); } } else { PoolVector::Write w = arr.write(); for (int j = 0; j < p_vertex_len; j++) { - const float *v = (const float *)&r[j * total_elem_size + offsets[i]]; + const float *v = (const float *)&r[j * strides[i] + offsets[i]]; w[j] = Vector2(v[0], v[1]); } } @@ -1610,14 +1682,14 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector::Write w = arr.write(); for (int j = 0; j < p_vertex_len; j++) { - const uint16_t *v = (const uint16_t *)&r[j * total_elem_size + offsets[i]]; + const uint16_t *v = (const uint16_t *)&r[j * strides[i] + offsets[i]]; w[j] = Vector2(Math::halfptr_to_float(&v[0]), Math::halfptr_to_float(&v[1])); } } else { PoolVector::Write w = arr.write(); for (int j = 0; j < p_vertex_len; j++) { - const float *v = (const float *)&r[j * total_elem_size + offsets[i]]; + const float *v = (const float *)&r[j * strides[i] + offsets[i]]; w[j] = Vector2(v[0], v[1]); } } @@ -1632,7 +1704,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector::Write w = arr.write(); for (int j = 0; j < p_vertex_len; j++) { - const uint16_t *v = (const uint16_t *)&r[j * total_elem_size + offsets[i]]; + const uint16_t *v = (const uint16_t *)&r[j * strides[i] + offsets[i]]; for (int k = 0; k < 4; k++) { w[j * 4 + k] = float(v[k] / 65535.0); } @@ -1641,7 +1713,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector::Write w = arr.write(); for (int j = 0; j < p_vertex_len; j++) { - const float *v = (const float *)&r[j * total_elem_size + offsets[i]]; + const float *v = (const float *)&r[j * strides[i] + offsets[i]]; for (int k = 0; k < 4; k++) { w[j * 4 + k] = v[k]; } @@ -1658,7 +1730,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector::Write w = arr.write(); for (int j = 0; j < p_vertex_len; j++) { - const uint16_t *v = (const uint16_t *)&r[j * total_elem_size + offsets[i]]; + const uint16_t *v = (const uint16_t *)&r[j * strides[i] + offsets[i]]; for (int k = 0; k < 4; k++) { w[j * 4 + k] = v[k]; } @@ -1667,7 +1739,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector::Write w = arr.write(); for (int j = 0; j < p_vertex_len; j++) { - const uint8_t *v = (const uint8_t *)&r[j * total_elem_size + offsets[i]]; + const uint8_t *v = (const uint8_t *)&r[j * strides[i] + offsets[i]]; for (int k = 0; k < 4; k++) { w[j * 4 + k] = v[k]; } @@ -1809,7 +1881,7 @@ void VisualServer::_bind_methods() { ClassDB::bind_method(D_METHOD("mesh_create"), &VisualServer::mesh_create); ClassDB::bind_method(D_METHOD("mesh_surface_get_format_offset", "format", "vertex_len", "index_len", "array_index"), &VisualServer::mesh_surface_get_format_offset); - ClassDB::bind_method(D_METHOD("mesh_surface_get_format_stride", "format", "vertex_len", "index_len"), &VisualServer::mesh_surface_get_format_stride); + ClassDB::bind_method(D_METHOD("mesh_surface_get_format_stride", "format", "vertex_len", "index_len", "array_index"), &VisualServer::mesh_surface_get_format_stride); ClassDB::bind_method(D_METHOD("mesh_add_surface_from_arrays", "mesh", "primitive", "arrays", "blend_shapes", "compress_format"), &VisualServer::mesh_add_surface_from_arrays, DEFVAL(Array()), DEFVAL(ARRAY_COMPRESS_DEFAULT)); ClassDB::bind_method(D_METHOD("mesh_set_blend_shape_count", "mesh", "amount"), &VisualServer::mesh_set_blend_shape_count); ClassDB::bind_method(D_METHOD("mesh_get_blend_shape_count", "mesh"), &VisualServer::mesh_get_blend_shape_count); @@ -2560,7 +2632,7 @@ VisualServer::VisualServer() { GLOBAL_DEF("rendering/quality/shading/force_blinn_over_ggx", false); GLOBAL_DEF("rendering/quality/shading/force_blinn_over_ggx.mobile", true); - GLOBAL_DEF("rendering/mesh_storage/split_stream", false); + GLOBAL_DEF_RST("rendering/mesh_storage/split_stream", false); GLOBAL_DEF("rendering/quality/depth_prepass/enable", true); GLOBAL_DEF("rendering/quality/depth_prepass/disable_for_vendors", "PowerVR,Mali,Adreno,Apple"); diff --git a/servers/visual_server.h b/servers/visual_server.h index 6d2c3f9826e..8347fdc8dc2 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -287,9 +287,9 @@ public: virtual RID mesh_create() = 0; virtual uint32_t mesh_surface_get_format_offset(uint32_t p_format, int p_vertex_len, int p_index_len, int p_array_index) const; - virtual uint32_t mesh_surface_get_format_stride(uint32_t p_format, int p_vertex_len, int p_index_len) const; + virtual uint32_t mesh_surface_get_format_stride(uint32_t p_format, int p_vertex_len, int p_index_len, int p_array_index) const; /// Returns stride - virtual uint32_t mesh_surface_make_offsets_from_format(uint32_t p_format, int p_vertex_len, int p_index_len, uint32_t *r_offsets) const; + virtual void mesh_surface_make_offsets_from_format(uint32_t p_format, int p_vertex_len, int p_index_len, uint32_t *r_offsets, uint32_t *r_strides) const; virtual void mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), uint32_t p_compress_format = ARRAY_COMPRESS_DEFAULT); virtual void mesh_add_surface(RID p_mesh, uint32_t p_format, PrimitiveType p_primitive, const PoolVector &p_array, int p_vertex_count, const PoolVector &p_index_array, int p_index_count, const AABB &p_aabb, const Vector> &p_blend_shapes = Vector>(), const Vector &p_bone_aabbs = Vector()) = 0;