diff --git a/doc/classes/VisualServer.xml b/doc/classes/VisualServer.xml index 5d1dc919c0b..1585aa55988 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 62616f4220f..8c59aab869c 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 eeb11290049..96cab1d0d40 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); @@ -2561,7 +2633,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 f6512d16c0c..28a17caf0f0 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;