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
This commit is contained in:
Omar El Sheikh 2021-08-16 20:41:43 -04:00
parent 4032d26dd5
commit a63028e172
9 changed files with 150 additions and 67 deletions

View File

@ -1958,8 +1958,8 @@
<argument index="0" name="format" type="int" />
<argument index="1" name="vertex_len" type="int" />
<argument index="2" name="index_len" type="int" />
<argument index="3" name="array_index" type="int" />
<description>
Function is unused in Godot 3.x.
</description>
</method>
<method name="mesh_surface_get_index_array" qualifiers="const">

View File

@ -2114,7 +2114,7 @@ static PoolVector<uint8_t> _unpack_half_floats(const PoolVector<uint8_t> &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<GL_BYTE> for memory bandwidth
// savings while keeping 4 byte alignment

View File

@ -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<GL_BYTE> for memory bandwidth
// savings while keeping 4 byte alignment

View File

@ -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];

View File

@ -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];
}

View File

@ -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();

View File

@ -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();

View File

@ -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<uint8_t> p_vertex_data, int p_vertex_len, PoolVector<uint8_t> 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<uint8_
}
int elem_size = 0;
switch (i) {
case VS::ARRAY_VERTEX: {
if (p_format & ARRAY_FLAG_USE_2D_VERTICES) {
@ -1297,6 +1338,14 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
elem_size = 8;
}
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) {
@ -1315,12 +1364,14 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
elem_size = sizeof(float) * 3;
}
}
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;
@ -1332,6 +1383,8 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
elem_size = sizeof(float) * 4;
}
}
offsets[i] = attributes_base_offset + attributes_stride;
attributes_stride += elem_size;
} break;
case VS::ARRAY_COLOR: {
@ -1340,6 +1393,9 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
} else {
elem_size = sizeof(float) * 4;
}
offsets[i] = attributes_base_offset + attributes_stride;
attributes_stride += elem_size;
} break;
case VS::ARRAY_TEX_UV: {
if (p_format & ARRAY_COMPRESS_TEX_UV) {
@ -1347,6 +1403,8 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
} else {
elem_size = sizeof(float) * 2;
}
offsets[i] = attributes_base_offset + attributes_stride;
attributes_stride += elem_size;
} break;
@ -1356,6 +1414,8 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
} else {
elem_size = sizeof(float) * 2;
}
offsets[i] = attributes_base_offset + attributes_stride;
attributes_stride += elem_size;
} break;
case VS::ARRAY_WEIGHTS: {
@ -1364,6 +1424,8 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
} else {
elem_size = sizeof(float) * 4;
}
offsets[i] = attributes_base_offset + attributes_stride;
attributes_stride += elem_size;
} break;
case VS::ARRAY_BONES: {
@ -1372,6 +1434,8 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
} else {
elem_size = sizeof(uint32_t);
}
offsets[i] = attributes_base_offset + attributes_stride;
attributes_stride += elem_size;
} break;
case VS::ARRAY_INDEX: {
@ -1393,9 +1457,17 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
ERR_FAIL_V(Array());
}
}
}
offsets[i] = total_elem_size;
total_elem_size += elem_size;
if (use_split_stream) {
strides[VS::ARRAY_VERTEX] = positions_stride;
for (int i = 1; i < VS::ARRAY_MAX - 1; i++) {
strides[i] = attributes_stride;
}
} else {
for (int i = 0; i < VS::ARRAY_MAX - 1; i++) {
strides[i] = positions_stride + attributes_stride;
}
}
Array ret;
@ -1418,14 +1490,14 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
PoolVector<Vector2>::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<Vector2>::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<uint8_
PoolVector<Vector3>::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<Vector3>::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<uint8_
PoolVector<Vector3>::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<uint8_
PoolVector<Vector3>::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<uint8_
const float multiplier = 1.f / 127.f;
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]];
w[j] = Vector3(float(v[0]) * multiplier, float(v[1]) * multiplier, float(v[2]) * multiplier);
}
} else {
PoolVector<Vector3>::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<uint8_
PoolVector<float>::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<uint8_
PoolVector<float>::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<uint8_
PoolVector<float>::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<uint8_
PoolVector<float>::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<uint8_
PoolVector<Color>::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<Color>::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<uint8_
PoolVector<Vector2>::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<Vector2>::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<uint8_
PoolVector<Vector2>::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<Vector2>::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<uint8_
PoolVector<float>::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<uint8_
PoolVector<float>::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<uint8_
PoolVector<int>::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<uint8_
PoolVector<int>::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");

View File

@ -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<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t>> &p_blend_shapes = Vector<PoolVector<uint8_t>>(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>()) = 0;