summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/templates/hashfuncs.h175
-rw-r--r--core/variant/variant.cpp96
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp47
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.h2
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp76
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h2
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp25
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h21
-rw-r--r--drivers/gles3/shaders/canvas.glsl10
-rw-r--r--drivers/gles3/shaders/scene.glsl24
-rw-r--r--drivers/gles3/storage/mesh_storage.cpp270
-rw-r--r--drivers/gles3/storage/mesh_storage.h1
-rw-r--r--modules/openxr/openxr_api.cpp6
-rw-r--r--modules/openxr/openxr_api.h6
-rw-r--r--modules/text_server_adv/text_server_adv.cpp2
-rw-r--r--modules/text_server_adv/text_server_adv.h2
-rw-r--r--modules/text_server_fb/text_server_fb.cpp2
-rw-r--r--modules/text_server_fb/text_server_fb.h2
18 files changed, 421 insertions, 348 deletions
diff --git a/core/templates/hashfuncs.h b/core/templates/hashfuncs.h
index 1330d55270..98ff7fa4ce 100644
--- a/core/templates/hashfuncs.h
+++ b/core/templates/hashfuncs.h
@@ -56,7 +56,7 @@
* @param C String
* @return 32-bits hashcode
*/
-static inline uint32_t hash_djb2(const char *p_cstr) {
+static _FORCE_INLINE_ uint32_t hash_djb2(const char *p_cstr) {
const unsigned char *chr = (const unsigned char *)p_cstr;
uint32_t hash = 5381;
uint32_t c;
@@ -68,7 +68,7 @@ static inline uint32_t hash_djb2(const char *p_cstr) {
return hash;
}
-static inline uint32_t hash_djb2_buffer(const uint8_t *p_buff, int p_len, uint32_t p_prev = 5381) {
+static _FORCE_INLINE_ uint32_t hash_djb2_buffer(const uint8_t *p_buff, int p_len, uint32_t p_prev = 5381) {
uint32_t hash = p_prev;
for (int i = 0; i < p_len; i++) {
@@ -78,7 +78,7 @@ static inline uint32_t hash_djb2_buffer(const uint8_t *p_buff, int p_len, uint32
return hash;
}
-static inline uint32_t hash_djb2_one_32(uint32_t p_in, uint32_t p_prev = 5381) {
+static _FORCE_INLINE_ uint32_t hash_djb2_one_32(uint32_t p_in, uint32_t p_prev = 5381) {
return ((p_prev << 5) + p_prev) + p_in;
}
@@ -89,7 +89,7 @@ static inline uint32_t hash_djb2_one_32(uint32_t p_in, uint32_t p_prev = 5381) {
* @param p_int - 64-bit unsigned integer key to be hashed
* @return unsigned 32-bit value representing hashcode
*/
-static inline uint32_t hash_one_uint64(const uint64_t p_int) {
+static _FORCE_INLINE_ uint32_t hash_one_uint64(const uint64_t p_int) {
uint64_t v = p_int;
v = (~v) + (v << 18); // v = (v << 18) - v - 1;
v = v ^ (v >> 31);
@@ -100,7 +100,72 @@ static inline uint32_t hash_one_uint64(const uint64_t p_int) {
return uint32_t(v);
}
-static inline uint32_t hash_djb2_one_float(double p_in, uint32_t p_prev = 5381) {
+// Murmurhash3 32-bit version.
+// All MurmurHash versions are public domain software, and the author disclaims all copyright to their code.
+
+static _FORCE_INLINE_ uint32_t rotl32(uint32_t x, int8_t r) {
+ return (x << r) | (x >> (32 - r));
+}
+
+static _FORCE_INLINE_ uint32_t fmix32(uint32_t h) {
+ h ^= h >> 16;
+ h *= 0x85ebca6b;
+ h ^= h >> 13;
+ h *= 0xc2b2ae35;
+ h ^= h >> 16;
+
+ return h;
+}
+
+static _FORCE_INLINE_ uint32_t hash_murmur3_32(const void *key, int length, const uint32_t seed = 0x7F07C65) {
+ // Although not required, this is a random prime number.
+ const uint8_t *data = (const uint8_t *)key;
+ const int nblocks = length / 4;
+
+ uint32_t h1 = seed;
+
+ const uint32_t c1 = 0xcc9e2d51;
+ const uint32_t c2 = 0x1b873593;
+
+ const uint32_t *blocks = (const uint32_t *)(data + nblocks * 4);
+
+ for (int i = -nblocks; i; i++) {
+ uint32_t k1 = blocks[i];
+
+ k1 *= c1;
+ k1 = rotl32(k1, 15);
+ k1 *= c2;
+
+ h1 ^= k1;
+ h1 = rotl32(h1, 13);
+ h1 = h1 * 5 + 0xe6546b64;
+ }
+
+ const uint8_t *tail = (const uint8_t *)(data + nblocks * 4);
+
+ uint32_t k1 = 0;
+
+ switch (length & 3) {
+ case 3:
+ k1 ^= tail[2] << 16;
+ [[fallthrough]];
+ case 2:
+ k1 ^= tail[1] << 8;
+ [[fallthrough]];
+ case 1:
+ k1 ^= tail[0];
+ k1 *= c1;
+ k1 = rotl32(k1, 15);
+ k1 *= c2;
+ h1 ^= k1;
+ };
+
+ // Finalize with additional bit mixing.
+ h1 ^= length;
+ return fmix32(h1);
+}
+
+static _FORCE_INLINE_ uint32_t hash_djb2_one_float(double p_in, uint32_t p_prev = 5381) {
union {
double d;
uint64_t i;
@@ -119,7 +184,7 @@ static inline uint32_t hash_djb2_one_float(double p_in, uint32_t p_prev = 5381)
}
template <class T>
-static inline uint32_t make_uint32_t(T p_in) {
+static _FORCE_INLINE_ uint32_t make_uint32_t(T p_in) {
union {
T t;
uint32_t _u32;
@@ -129,7 +194,7 @@ static inline uint32_t make_uint32_t(T p_in) {
return _u._u32;
}
-static inline uint64_t hash_djb2_one_float_64(double p_in, uint64_t p_prev = 5381) {
+static _FORCE_INLINE_ uint64_t hash_djb2_one_float_64(double p_in, uint64_t p_prev = 5381) {
union {
double d;
uint64_t i;
@@ -147,12 +212,12 @@ static inline uint64_t hash_djb2_one_float_64(double p_in, uint64_t p_prev = 538
return ((p_prev << 5) + p_prev) + u.i;
}
-static inline uint64_t hash_djb2_one_64(uint64_t p_in, uint64_t p_prev = 5381) {
+static _FORCE_INLINE_ uint64_t hash_djb2_one_64(uint64_t p_in, uint64_t p_prev = 5381) {
return ((p_prev << 5) + p_prev) + p_in;
}
template <class T>
-static inline uint64_t make_uint64_t(T p_in) {
+static _FORCE_INLINE_ uint64_t make_uint64_t(T p_in) {
union {
T t;
uint64_t _u64;
@@ -167,78 +232,40 @@ template <class T>
class Ref;
struct HashMapHasherDefault {
- static _FORCE_INLINE_ uint32_t hash(const String &p_string) { return p_string.hash(); }
- static _FORCE_INLINE_ uint32_t hash(const char *p_cstr) { return hash_djb2(p_cstr); }
- static _FORCE_INLINE_ uint32_t hash(const uint64_t p_int) { return hash_one_uint64(p_int); }
- static _FORCE_INLINE_ uint32_t hash(const ObjectID &p_id) { return hash_one_uint64(p_id); }
-
- static _FORCE_INLINE_ uint32_t hash(const int64_t p_int) { return hash(uint64_t(p_int)); }
- static _FORCE_INLINE_ uint32_t hash(const float p_float) { return hash_djb2_one_float(p_float); }
- static _FORCE_INLINE_ uint32_t hash(const double p_double) { return hash_djb2_one_float(p_double); }
- static _FORCE_INLINE_ uint32_t hash(const uint32_t p_int) { return p_int; }
- static _FORCE_INLINE_ uint32_t hash(const int32_t p_int) { return (uint32_t)p_int; }
- static _FORCE_INLINE_ uint32_t hash(const uint16_t p_int) { return p_int; }
- static _FORCE_INLINE_ uint32_t hash(const int16_t p_int) { return (uint32_t)p_int; }
- static _FORCE_INLINE_ uint32_t hash(const uint8_t p_int) { return p_int; }
- static _FORCE_INLINE_ uint32_t hash(const int8_t p_int) { return (uint32_t)p_int; }
- static _FORCE_INLINE_ uint32_t hash(const wchar_t p_wchar) { return (uint32_t)p_wchar; }
- static _FORCE_INLINE_ uint32_t hash(const char16_t p_uchar) { return (uint32_t)p_uchar; }
- static _FORCE_INLINE_ uint32_t hash(const char32_t p_uchar) { return (uint32_t)p_uchar; }
- static _FORCE_INLINE_ uint32_t hash(const RID &p_rid) { return hash_one_uint64(p_rid.get_id()); }
-
- static _FORCE_INLINE_ uint32_t hash(const StringName &p_string_name) { return p_string_name.hash(); }
- static _FORCE_INLINE_ uint32_t hash(const NodePath &p_path) { return p_path.hash(); }
-
+ // Generic hash function for any type.
template <class T>
static _FORCE_INLINE_ uint32_t hash(const T *p_pointer) { return hash_one_uint64((uint64_t)p_pointer); }
template <class T>
static _FORCE_INLINE_ uint32_t hash(const Ref<T> &p_ref) { return hash_one_uint64((uint64_t)p_ref.operator->()); }
- static _FORCE_INLINE_ uint32_t hash(const Vector2i &p_vec) {
- uint32_t h = hash_djb2_one_32(p_vec.x);
- return hash_djb2_one_32(p_vec.y, h);
- }
- static _FORCE_INLINE_ uint32_t hash(const Vector3i &p_vec) {
- uint32_t h = hash_djb2_one_32(p_vec.x);
- h = hash_djb2_one_32(p_vec.y, h);
- return hash_djb2_one_32(p_vec.z, h);
- }
-
- static _FORCE_INLINE_ uint32_t hash(const Vector2 &p_vec) {
- uint32_t h = hash_djb2_one_float(p_vec.x);
- return hash_djb2_one_float(p_vec.y, h);
- }
- static _FORCE_INLINE_ uint32_t hash(const Vector3 &p_vec) {
- uint32_t h = hash_djb2_one_float(p_vec.x);
- h = hash_djb2_one_float(p_vec.y, h);
- return hash_djb2_one_float(p_vec.z, h);
- }
-
- static _FORCE_INLINE_ uint32_t hash(const Rect2i &p_rect) {
- uint32_t h = hash_djb2_one_32(p_rect.position.x);
- h = hash_djb2_one_32(p_rect.position.y, h);
- h = hash_djb2_one_32(p_rect.size.x, h);
- return hash_djb2_one_32(p_rect.size.y, h);
- }
-
- static _FORCE_INLINE_ uint32_t hash(const Rect2 &p_rect) {
- uint32_t h = hash_djb2_one_float(p_rect.position.x);
- h = hash_djb2_one_float(p_rect.position.y, h);
- h = hash_djb2_one_float(p_rect.size.x, h);
- return hash_djb2_one_float(p_rect.size.y, h);
- }
-
- static _FORCE_INLINE_ uint32_t hash(const AABB &p_aabb) {
- uint32_t h = hash_djb2_one_float(p_aabb.position.x);
- h = hash_djb2_one_float(p_aabb.position.y, h);
- h = hash_djb2_one_float(p_aabb.position.z, h);
- h = hash_djb2_one_float(p_aabb.size.x, h);
- h = hash_djb2_one_float(p_aabb.size.y, h);
- return hash_djb2_one_float(p_aabb.size.z, h);
- }
+ static _FORCE_INLINE_ uint32_t hash(const String &p_string) { return p_string.hash(); }
+ static _FORCE_INLINE_ uint32_t hash(const char *p_cstr) { return hash_djb2(p_cstr); }
+ static _FORCE_INLINE_ uint32_t hash(const wchar_t p_wchar) { return fmix32(p_wchar); }
+ static _FORCE_INLINE_ uint32_t hash(const char16_t p_uchar) { return fmix32(p_uchar); }
+ static _FORCE_INLINE_ uint32_t hash(const char32_t p_uchar) { return fmix32(p_uchar); }
+ static _FORCE_INLINE_ uint32_t hash(const RID &p_rid) { return hash_one_uint64(p_rid.get_id()); }
+ static _FORCE_INLINE_ uint32_t hash(const StringName &p_string_name) { return p_string_name.hash(); }
+ static _FORCE_INLINE_ uint32_t hash(const NodePath &p_path) { return p_path.hash(); }
+ static _FORCE_INLINE_ uint32_t hash(const ObjectID &p_id) { return hash_one_uint64(p_id); }
- //static _FORCE_INLINE_ uint32_t hash(const void* p_ptr) { return uint32_t(uint64_t(p_ptr))*(0x9e3779b1L); }
+ static _FORCE_INLINE_ uint32_t hash(const uint64_t p_int) { return hash_one_uint64(p_int); }
+ static _FORCE_INLINE_ uint32_t hash(const int64_t p_int) { return hash_one_uint64(p_int); }
+ static _FORCE_INLINE_ uint32_t hash(const float p_float) { return hash_djb2_one_float(p_float); }
+ static _FORCE_INLINE_ uint32_t hash(const double p_double) { return hash_djb2_one_float(p_double); }
+ static _FORCE_INLINE_ uint32_t hash(const uint32_t p_int) { return fmix32(p_int); }
+ static _FORCE_INLINE_ uint32_t hash(const int32_t p_int) { return fmix32(p_int); }
+ static _FORCE_INLINE_ uint32_t hash(const uint16_t p_int) { return fmix32(p_int); }
+ static _FORCE_INLINE_ uint32_t hash(const int16_t p_int) { return fmix32(p_int); }
+ static _FORCE_INLINE_ uint32_t hash(const uint8_t p_int) { return fmix32(p_int); }
+ static _FORCE_INLINE_ uint32_t hash(const int8_t p_int) { return fmix32(p_int); }
+ static _FORCE_INLINE_ uint32_t hash(const Vector2i &p_vec) { return hash_murmur3_32(&p_vec, sizeof(Vector2i)); }
+ static _FORCE_INLINE_ uint32_t hash(const Vector3i &p_vec) { return hash_murmur3_32(&p_vec, sizeof(Vector3i)); }
+ static _FORCE_INLINE_ uint32_t hash(const Vector2 &p_vec) { return hash_murmur3_32(&p_vec, sizeof(Vector2)); }
+ static _FORCE_INLINE_ uint32_t hash(const Vector3 &p_vec) { return hash_murmur3_32(&p_vec, sizeof(Vector3)); }
+ static _FORCE_INLINE_ uint32_t hash(const Rect2i &p_rect) { return hash_murmur3_32(&p_rect, sizeof(Rect2i)); }
+ static _FORCE_INLINE_ uint32_t hash(const Rect2 &p_rect) { return hash_murmur3_32(&p_rect, sizeof(Rect2)); }
+ static _FORCE_INLINE_ uint32_t hash(const AABB &p_aabb) { return hash_murmur3_32(&p_aabb, sizeof(AABB)); }
};
template <typename T>
diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp
index 2b4e777865..aa640924e4 100644
--- a/core/variant/variant.cpp
+++ b/core/variant/variant.cpp
@@ -2788,106 +2788,50 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
// math types
case VECTOR2: {
- uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Vector2 *>(_data._mem)->x);
- return hash_djb2_one_float(reinterpret_cast<const Vector2 *>(_data._mem)->y, hash);
+ return hash_murmur3_32(reinterpret_cast<const Vector2 *>(_data._mem), sizeof(Vector2));
} break;
case VECTOR2I: {
- uint32_t hash = hash_djb2_one_32((uint32_t) reinterpret_cast<const Vector2i *>(_data._mem)->x);
- return hash_djb2_one_32((uint32_t) reinterpret_cast<const Vector2i *>(_data._mem)->y, hash);
+ return hash_murmur3_32(reinterpret_cast<const Vector2i *>(_data._mem), sizeof(Vector2i));
} break;
case RECT2: {
- uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->position.x);
- hash = hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->position.y, hash);
- hash = hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->size.x, hash);
- return hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->size.y, hash);
+ return hash_murmur3_32(reinterpret_cast<const Rect2 *>(_data._mem), sizeof(Rect2));
} break;
case RECT2I: {
- uint32_t hash = hash_djb2_one_32((uint32_t) reinterpret_cast<const Rect2i *>(_data._mem)->position.x);
- hash = hash_djb2_one_32((uint32_t) reinterpret_cast<const Rect2i *>(_data._mem)->position.y, hash);
- hash = hash_djb2_one_32((uint32_t) reinterpret_cast<const Rect2i *>(_data._mem)->size.x, hash);
- return hash_djb2_one_32((uint32_t) reinterpret_cast<const Rect2i *>(_data._mem)->size.y, hash);
+ return hash_murmur3_32(reinterpret_cast<const Rect2i *>(_data._mem), sizeof(Rect2i));
} break;
case TRANSFORM2D: {
- uint32_t hash = 5831;
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 2; j++) {
- hash = hash_djb2_one_float(_data._transform2d->columns[i][j], hash);
- }
- }
-
- return hash;
+ return hash_murmur3_32(reinterpret_cast<const Transform2D *>(_data._transform2d), sizeof(Transform2D));
} break;
case VECTOR3: {
- uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Vector3 *>(_data._mem)->x);
- hash = hash_djb2_one_float(reinterpret_cast<const Vector3 *>(_data._mem)->y, hash);
- return hash_djb2_one_float(reinterpret_cast<const Vector3 *>(_data._mem)->z, hash);
+ return hash_murmur3_32(reinterpret_cast<const Vector3 *>(_data._mem), sizeof(Vector3));
} break;
case VECTOR3I: {
- uint32_t hash = hash_djb2_one_32((uint32_t) reinterpret_cast<const Vector3i *>(_data._mem)->x);
- hash = hash_djb2_one_32((uint32_t) reinterpret_cast<const Vector3i *>(_data._mem)->y, hash);
- return hash_djb2_one_32((uint32_t) reinterpret_cast<const Vector3i *>(_data._mem)->z, hash);
+ return hash_murmur3_32(reinterpret_cast<const Vector3i *>(_data._mem), sizeof(Vector3i));
} break;
case PLANE: {
- uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Plane *>(_data._mem)->normal.x);
- hash = hash_djb2_one_float(reinterpret_cast<const Plane *>(_data._mem)->normal.y, hash);
- hash = hash_djb2_one_float(reinterpret_cast<const Plane *>(_data._mem)->normal.z, hash);
- return hash_djb2_one_float(reinterpret_cast<const Plane *>(_data._mem)->d, hash);
-
+ return hash_murmur3_32(reinterpret_cast<const Plane *>(_data._mem), sizeof(Plane));
} break;
case AABB: {
- uint32_t hash = 5831;
- for (int i = 0; i < 3; i++) {
- hash = hash_djb2_one_float(_data._aabb->position[i], hash);
- hash = hash_djb2_one_float(_data._aabb->size[i], hash);
- }
-
- return hash;
-
+ return hash_murmur3_32(_data._aabb, sizeof(AABB));
} break;
case QUATERNION: {
- uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Quaternion *>(_data._mem)->x);
- hash = hash_djb2_one_float(reinterpret_cast<const Quaternion *>(_data._mem)->y, hash);
- hash = hash_djb2_one_float(reinterpret_cast<const Quaternion *>(_data._mem)->z, hash);
- return hash_djb2_one_float(reinterpret_cast<const Quaternion *>(_data._mem)->w, hash);
-
+ return hash_murmur3_32(reinterpret_cast<const Quaternion *>(_data._mem), sizeof(Quaternion));
} break;
case BASIS: {
- uint32_t hash = 5831;
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 3; j++) {
- hash = hash_djb2_one_float(_data._basis->rows[i][j], hash);
- }
- }
-
- return hash;
-
+ return hash_murmur3_32(_data._basis, sizeof(Basis));
} break;
case TRANSFORM3D: {
- uint32_t hash = 5831;
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 3; j++) {
- hash = hash_djb2_one_float(_data._transform3d->basis.rows[i][j], hash);
- }
- hash = hash_djb2_one_float(_data._transform3d->origin[i], hash);
- }
-
- return hash;
-
+ return hash_murmur3_32(_data._transform3d, sizeof(Transform3D));
} break;
-
// misc types
case COLOR: {
- uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Color *>(_data._mem)->r);
- hash = hash_djb2_one_float(reinterpret_cast<const Color *>(_data._mem)->g, hash);
- hash = hash_djb2_one_float(reinterpret_cast<const Color *>(_data._mem)->b, hash);
- return hash_djb2_one_float(reinterpret_cast<const Color *>(_data._mem)->a, hash);
-
+ return hash_murmur3_32(reinterpret_cast<const Color *>(_data._mem), sizeof(Color));
} break;
case RID: {
- return hash_djb2_one_64(reinterpret_cast<const ::RID *>(_data._mem)->get_id());
+ return hash_one_uint64(reinterpret_cast<const ::RID *>(_data._mem)->get_id());
} break;
case OBJECT: {
- return hash_djb2_one_64(make_uint64_t(_get_obj().obj));
+ return hash_one_uint64(make_uint64_t(_get_obj().obj));
} break;
case STRING_NAME: {
return reinterpret_cast<const StringName *>(_data._mem)->hash();
@@ -2918,7 +2862,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
int len = arr.size();
if (likely(len)) {
const uint8_t *r = arr.ptr();
- return hash_djb2_buffer((uint8_t *)&r[0], len);
+ return hash_murmur3_32((uint8_t *)&r[0], len);
} else {
return hash_djb2_one_64(0);
}
@@ -2929,7 +2873,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
int len = arr.size();
if (likely(len)) {
const int32_t *r = arr.ptr();
- return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(int32_t));
+ return hash_murmur3_32((uint8_t *)&r[0], len * sizeof(int32_t));
} else {
return hash_djb2_one_64(0);
}
@@ -2940,7 +2884,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
int len = arr.size();
if (likely(len)) {
const int64_t *r = arr.ptr();
- return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(int64_t));
+ return hash_murmur3_32((uint8_t *)&r[0], len * sizeof(int64_t));
} else {
return hash_djb2_one_64(0);
}
@@ -2952,7 +2896,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
if (likely(len)) {
const float *r = arr.ptr();
- return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(float));
+ return hash_murmur3_32((uint8_t *)&r[0], len * sizeof(float));
} else {
return hash_djb2_one_float(0.0);
}
@@ -2964,7 +2908,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
if (likely(len)) {
const double *r = arr.ptr();
- return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(double));
+ return hash_murmur3_32((uint8_t *)&r[0], len * sizeof(double));
} else {
return hash_djb2_one_float(0.0);
}
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 32d279a635..d41c844d1d 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -689,6 +689,10 @@ void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item
_bind_instance_data_buffer(1);
glBindVertexArray(pb->vertex_array);
+ if (pb->color_disabled) {
+ glVertexAttrib4f(RS::ARRAY_COLOR, pb->color.r, pb->color.g, pb->color.b, pb->color.a);
+ }
+
if (pb->index_buffer != 0) {
glDrawElements(prim[polygon->primitive], pb->count, GL_UNSIGNED_INT, nullptr);
} else {
@@ -698,6 +702,11 @@ void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item
state.fences[state.current_buffer] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
state.current_buffer = (state.current_buffer + 1) % state.canvas_instance_data_buffers.size();
+
+ if (pb->color_disabled) {
+ // Reset so this doesn't pollute other draw calls.
+ glVertexAttrib4f(RS::ARRAY_COLOR, 1.0, 1.0, 1.0, 1.0);
+ }
} break;
case Item::Command::TYPE_PRIMITIVE: {
@@ -758,7 +767,6 @@ void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item
GLuint multimesh_buffer = 0;
uint32_t multimesh_stride = 0;
uint32_t multimesh_color_offset = 0;
- uint32_t multimesh_custom_data_offset = 0;
bool multimesh_uses_color = false;
bool multimesh_uses_custom_data = false;
@@ -788,7 +796,6 @@ void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item
multimesh_buffer = mesh_storage->multimesh_get_gl_buffer(multimesh);
multimesh_stride = mesh_storage->multimesh_get_stride(multimesh);
multimesh_color_offset = mesh_storage->multimesh_get_color_offset(multimesh);
- multimesh_custom_data_offset = mesh_storage->multimesh_get_custom_data_offset(multimesh);
multimesh_uses_color = mesh_storage->multimesh_uses_colors(multimesh);
multimesh_uses_custom_data = mesh_storage->multimesh_uses_custom_data(multimesh);
}
@@ -854,22 +861,17 @@ void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item
if (instance_count > 1) {
// Bind instance buffers.
glBindBuffer(GL_ARRAY_BUFFER, multimesh_buffer);
- glEnableVertexAttribArray(5);
- glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, multimesh_stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(0));
- glVertexAttribDivisor(5, 1);
- glEnableVertexAttribArray(6);
- glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, multimesh_stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(4 * 4));
- glVertexAttribDivisor(6, 1);
-
- if (multimesh_uses_color) {
- glEnableVertexAttribArray(7);
- glVertexAttribPointer(7, 4, GL_FLOAT, GL_FALSE, multimesh_stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(multimesh_color_offset * sizeof(float)));
- glVertexAttribDivisor(7, 1);
- }
- if (multimesh_uses_custom_data) {
- glEnableVertexAttribArray(8);
- glVertexAttribPointer(8, 4, GL_FLOAT, GL_FALSE, multimesh_stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(multimesh_custom_data_offset * sizeof(float)));
- glVertexAttribDivisor(8, 1);
+ glEnableVertexAttribArray(1);
+ glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, multimesh_stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(0));
+ glVertexAttribDivisor(1, 1);
+ glEnableVertexAttribArray(2);
+ glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, multimesh_stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(4 * 4));
+ glVertexAttribDivisor(2, 1);
+
+ if (multimesh_uses_color || multimesh_uses_custom_data) {
+ glEnableVertexAttribArray(5);
+ glVertexAttribIPointer(5, 4, GL_UNSIGNED_INT, multimesh_stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(multimesh_color_offset * sizeof(float)));
+ glVertexAttribDivisor(5, 1);
}
}
@@ -1268,11 +1270,7 @@ RendererCanvasRender::PolygonID RasterizerCanvasGLES3::request_polygon(const Vec
}
// Next add colors
- if (p_colors.size() == 1) {
- glDisableVertexAttribArray(RS::ARRAY_COLOR);
- Color m = p_colors[0];
- glVertexAttrib4f(RS::ARRAY_COLOR, m.r, m.g, m.b, m.a);
- } else if ((uint32_t)p_colors.size() == vertex_count) {
+ if ((uint32_t)p_colors.size() == vertex_count) {
glEnableVertexAttribArray(RS::ARRAY_COLOR);
glVertexAttribPointer(RS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(base_offset * sizeof(float)));
@@ -1287,7 +1285,8 @@ RendererCanvasRender::PolygonID RasterizerCanvasGLES3::request_polygon(const Vec
base_offset += 4;
} else {
glDisableVertexAttribArray(RS::ARRAY_COLOR);
- glVertexAttrib4f(RS::ARRAY_COLOR, 1.0, 1.0, 1.0, 1.0);
+ pb.color_disabled = true;
+ pb.color = p_colors.size() == 1 ? p_colors[0] : Color(1.0, 1.0, 1.0, 1.0);
}
if ((uint32_t)p_uvs.size() == vertex_count) {
diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h
index 31e82401f9..bf13c91e1c 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.h
+++ b/drivers/gles3/rasterizer_canvas_gles3.h
@@ -238,6 +238,8 @@ public:
GLuint vertex_array;
GLuint index_buffer;
int count;
+ bool color_disabled = false;
+ Color color;
};
struct {
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 3fe0ae4876..94ae8ecc8a 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -491,7 +491,7 @@ void RasterizerSceneGLES3::_geometry_instance_update(GeometryInstance *p_geometr
}
}
- ginstance->instance_count = 1;
+ ginstance->instance_count = -1;
} break;
@@ -2200,6 +2200,7 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
GLES3::SceneMaterialData *prev_material_data = nullptr;
GLES3::SceneShaderData *prev_shader = nullptr;
GeometryInstanceGLES3 *prev_inst = nullptr;
+ SceneShaderGLES3::ShaderVariant prev_variant = SceneShaderGLES3::ShaderVariant::MODE_COLOR;
SceneShaderGLES3::ShaderVariant shader_variant = SceneShaderGLES3::MODE_COLOR; // Assigned to silence wrong -Wmaybe-initialized.
@@ -2386,12 +2387,11 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
prev_vertex_array_gl = vertex_array_gl;
}
- bool use_index_buffer = false;
+ bool use_index_buffer = index_array_gl != 0;
if (prev_index_array_gl != index_array_gl) {
if (index_array_gl != 0) {
// Bind index each time so we can use LODs
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_array_gl);
- use_index_buffer = true;
}
prev_index_array_gl = index_array_gl;
}
@@ -2406,8 +2406,13 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
prev_material_data = material_data;
}
- if (prev_shader != shader) {
- material_storage->shaders.scene_shader.version_bind_shader(shader->version, shader_variant);
+ SceneShaderGLES3::ShaderVariant instance_variant = shader_variant;
+ if (inst->instance_count > 0) {
+ instance_variant = SceneShaderGLES3::ShaderVariant(1 + int(shader_variant));
+ }
+
+ if (prev_shader != shader || prev_variant != instance_variant) {
+ material_storage->shaders.scene_shader.version_bind_shader(shader->version, instance_variant);
float opaque_prepass_threshold = 0.0;
if (p_pass_mode == PASS_MODE_DEPTH) {
opaque_prepass_threshold = 0.99;
@@ -2415,33 +2420,69 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
opaque_prepass_threshold = 0.1;
}
- material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::OPAQUE_PREPASS_THRESHOLD, opaque_prepass_threshold, shader->version, shader_variant);
+ material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::OPAQUE_PREPASS_THRESHOLD, opaque_prepass_threshold, shader->version, instance_variant);
prev_shader = shader;
+ prev_variant = instance_variant;
}
- if (prev_inst != inst) {
+ if (prev_inst != inst || prev_shader != shader || prev_variant != instance_variant) {
// Rebind the light indices.
- material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::OMNI_LIGHT_COUNT, inst->omni_light_count, shader->version, shader_variant);
- material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::SPOT_LIGHT_COUNT, inst->spot_light_count, shader->version, shader_variant);
+ material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::OMNI_LIGHT_COUNT, inst->omni_light_count, shader->version, instance_variant);
+ material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::SPOT_LIGHT_COUNT, inst->spot_light_count, shader->version, instance_variant);
if (inst->omni_light_count) {
- glUniform1uiv(material_storage->shaders.scene_shader.version_get_uniform(SceneShaderGLES3::OMNI_LIGHT_INDICES, shader->version, shader_variant), inst->omni_light_count, inst->omni_light_gl_cache.ptr());
+ glUniform1uiv(material_storage->shaders.scene_shader.version_get_uniform(SceneShaderGLES3::OMNI_LIGHT_INDICES, shader->version, instance_variant), inst->omni_light_count, inst->omni_light_gl_cache.ptr());
}
if (inst->spot_light_count) {
- glUniform1uiv(material_storage->shaders.scene_shader.version_get_uniform(SceneShaderGLES3::SPOT_LIGHT_INDICES, shader->version, shader_variant), inst->spot_light_count, inst->spot_light_gl_cache.ptr());
+ glUniform1uiv(material_storage->shaders.scene_shader.version_get_uniform(SceneShaderGLES3::SPOT_LIGHT_INDICES, shader->version, instance_variant), inst->spot_light_count, inst->spot_light_gl_cache.ptr());
}
prev_inst = inst;
}
- material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, world_transform, shader->version, shader_variant);
-
- if (use_index_buffer) {
- glDrawElements(primitive_gl, mesh_storage->mesh_surface_get_vertices_drawn_count(mesh_surface), mesh_storage->mesh_surface_get_index_type(mesh_surface), 0);
+ material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, world_transform, shader->version, instance_variant);
+ if (inst->instance_count > 0) {
+ // Using MultiMesh.
+ // Bind instance buffers.
+
+ GLuint multimesh_buffer = mesh_storage->multimesh_get_gl_buffer(inst->data->base);
+ glBindBuffer(GL_ARRAY_BUFFER, multimesh_buffer);
+ uint32_t multimesh_stride = mesh_storage->multimesh_get_stride(inst->data->base);
+ glEnableVertexAttribArray(12);
+ glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, multimesh_stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(0));
+ glVertexAttribDivisor(12, 1);
+ glEnableVertexAttribArray(13);
+ glVertexAttribPointer(13, 4, GL_FLOAT, GL_FALSE, multimesh_stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(4 * 4));
+ glVertexAttribDivisor(13, 1);
+ glEnableVertexAttribArray(14);
+ glVertexAttribPointer(14, 4, GL_FLOAT, GL_FALSE, multimesh_stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(4 * 8));
+ glVertexAttribDivisor(14, 1);
+
+ if (mesh_storage->multimesh_uses_colors(inst->data->base) || mesh_storage->multimesh_uses_custom_data(inst->data->base)) {
+ glEnableVertexAttribArray(15);
+ glVertexAttribIPointer(15, 4, GL_UNSIGNED_INT, multimesh_stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(mesh_storage->multimesh_get_color_offset(inst->data->base) * sizeof(float)));
+ glVertexAttribDivisor(15, 1);
+ }
+ if (use_index_buffer) {
+ glDrawElementsInstanced(primitive_gl, mesh_storage->mesh_surface_get_vertices_drawn_count(mesh_surface), mesh_storage->mesh_surface_get_index_type(mesh_surface), 0, inst->instance_count);
+ } else {
+ glDrawArraysInstanced(primitive_gl, 0, mesh_storage->mesh_surface_get_vertices_drawn_count(mesh_surface), inst->instance_count);
+ }
} else {
- glDrawArrays(primitive_gl, 0, mesh_storage->mesh_surface_get_vertices_drawn_count(mesh_surface));
+ // Using regular Mesh.
+ if (use_index_buffer) {
+ glDrawElements(primitive_gl, mesh_storage->mesh_surface_get_vertices_drawn_count(mesh_surface), mesh_storage->mesh_surface_get_index_type(mesh_surface), 0);
+ } else {
+ glDrawArrays(primitive_gl, 0, mesh_storage->mesh_surface_get_vertices_drawn_count(mesh_surface));
+ }
+ }
+ if (inst->instance_count > 0) {
+ glDisableVertexAttribArray(12);
+ glDisableVertexAttribArray(13);
+ glDisableVertexAttribArray(14);
+ glDisableVertexAttribArray(15);
}
}
}
@@ -2811,6 +2852,9 @@ void sky() {
#ifdef GLES_OVER_GL
glEnable(_EXT_TEXTURE_CUBE_MAP_SEAMLESS);
#endif
+
+ // MultiMesh may read from color when color is disabled, so make sure that the color defaults to white instead of black;
+ glVertexAttrib4f(RS::ARRAY_COLOR, 1.0, 1.0, 1.0, 1.0);
}
RasterizerSceneGLES3::~RasterizerSceneGLES3() {
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index f76861bc90..308ef36fa1 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -277,7 +277,7 @@ private:
int32_t shader_parameters_offset = -1;
uint32_t layer_mask = 1;
- uint32_t instance_count = 0;
+ int32_t instance_count = 0;
RID mesh_instance;
bool can_sdfgi = false;
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 012cda953c..bbe4d92856 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -38,6 +38,8 @@
#include "rasterizer_scene_gles3.h"
#include "servers/rendering/shader_language.h"
+/* MISC */
+
void RasterizerStorageGLES3::base_update_dependency(RID p_base, DependencyTracker *p_instance) {
if (GLES3::MeshStorage::get_singleton()->owns_mesh(p_base)) {
GLES3::Mesh *mesh = GLES3::MeshStorage::get_singleton()->get_mesh(p_base);
@@ -54,6 +56,29 @@ void RasterizerStorageGLES3::base_update_dependency(RID p_base, DependencyTracke
}
}
+Vector<uint8_t> RasterizerStorageGLES3::buffer_get_data(GLenum p_target, GLuint p_buffer, uint32_t p_buffer_size) {
+ Vector<uint8_t> ret;
+ ret.resize(p_buffer_size);
+ glBindBuffer(p_target, p_buffer);
+
+#if defined(__EMSCRIPTEN__)
+ {
+ uint8_t *w = ret.ptrw();
+ glGetBufferSubData(p_target, 0, p_buffer_size, w);
+ }
+#else
+ void *data = glMapBufferRange(p_target, 0, p_buffer_size, GL_MAP_READ_BIT);
+ ERR_FAIL_NULL_V(data, Vector<uint8_t>());
+ {
+ uint8_t *w = ret.ptrw();
+ memcpy(w, data, p_buffer_size);
+ }
+ glUnmapBuffer(p_target);
+#endif
+ glBindBuffer(p_target, 0);
+ return ret;
+}
+
/* VOXEL GI API */
RID RasterizerStorageGLES3::voxel_gi_allocate() {
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 7ac3db4537..981080f6a5 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -98,6 +98,9 @@ public:
}
}
+ // Buffer size is specified in bytes
+ static Vector<uint8_t> buffer_get_data(GLenum p_target, GLuint p_buffer, uint32_t p_buffer_size);
+
struct Resources {
GLuint mipmap_blur_fbo;
GLuint mipmap_blur_color;
@@ -295,28 +298,10 @@ public:
return String();
}
- //bool validate_framebuffer(); // Validate currently bound framebuffer, does not touch global state
- String get_framebuffer_error(GLenum p_status);
-
RasterizerStorageGLES3();
~RasterizerStorageGLES3();
};
-inline String RasterizerStorageGLES3::get_framebuffer_error(GLenum p_status) {
-#if defined(DEBUG_ENABLED) && defined(GLES_OVER_GL)
- if (p_status == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT) {
- return "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
- } else if (p_status == GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) {
- return "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
- } else if (p_status == GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER) {
- return "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER";
- } else if (p_status == GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER) {
- return "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER";
- }
-#endif
- return itos(p_status);
-}
-
#endif // GLES3_ENABLED
#endif // RASTERIZER_STORAGE_OPENGL_H
diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl
index 9c426dd3ef..4df818cd4c 100644
--- a/drivers/gles3/shaders/canvas.glsl
+++ b/drivers/gles3/shaders/canvas.glsl
@@ -23,10 +23,9 @@ layout(location = 11) in vec4 weight_attrib;
#ifdef USE_INSTANCING
-layout(location = 5) in highp vec4 instance_xform0;
-layout(location = 6) in highp vec4 instance_xform1;
-layout(location = 7) in lowp vec4 instance_color;
-layout(location = 8) in highp vec4 instance_custom_data;
+layout(location = 1) in highp vec4 instance_xform0;
+layout(location = 2) in highp vec4 instance_xform1;
+layout(location = 5) in highp uvec4 instance_color_custom_data; // Color packed into xy, custom_data packed into zw for compatibility with 3D
#endif
@@ -98,8 +97,9 @@ void main() {
vec4 bone_weights = weight_attrib;
#ifdef USE_INSTANCING
+ vec4 instance_color = vec4(unpackHalf2x16(instance_color_custom_data.x), unpackHalf2x16(instance_color_custom_data.y));
color *= instance_color;
- instance_custom = instance_custom_data;
+ instance_custom = vec4(unpackHalf2x16(instance_color_custom_data.z), unpackHalf2x16(instance_color_custom_data.w));
#endif
#else
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index fbea4bdbe4..4f2be8bf60 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -2,8 +2,11 @@
#[modes]
mode_color = #define BASE_PASS
+mode_color_instancing = #define BASE_PASS \n#define USE_INSTANCING
mode_additive = #define USE_ADDITIVE_LIGHTING
+mode_additive_instancing = #define USE_ADDITIVE_LIGHTING \n#define USE_INSTANCING
mode_depth = #define MODE_RENDER_DEPTH
+mode_depth_instancing = #define MODE_RENDER_DEPTH \n#define USE_INSTANCING
#[specializations]
@@ -43,8 +46,6 @@ ARRAY_CUSTOM2 = 8,
ARRAY_CUSTOM3 = 9,
ARRAY_BONES = 10, // RGBA16UI (x2 if 8 weights)
ARRAY_WEIGHTS = 11, // RGBA16UNORM (x2 if 8 weights)
-ARRAY_INDEX = 12, // 16 or 32 bits depending on length > 0xFFFF.
-ARRAY_MAX = 13
*/
/* INPUT ATTRIBS */
@@ -96,6 +97,13 @@ layout(location = 10) in uvec4 bone_attrib;
layout(location = 11) in vec4 weight_attrib;
#endif
+#ifdef USE_INSTANCING
+layout(location = 12) in highp vec4 instance_xform0;
+layout(location = 13) in highp vec4 instance_xform1;
+layout(location = 14) in highp vec4 instance_xform2;
+layout(location = 15) in highp uvec4 instance_color_custom_data; // Color packed into xy, Custom data into zw.
+#endif
+
layout(std140) uniform GlobalVariableData { //ubo:1
vec4 global_variables[MAX_GLOBAL_VARIABLES];
};
@@ -195,6 +203,10 @@ void main() {
highp vec3 vertex = vertex_attrib;
highp mat4 model_matrix = world_transform;
+#ifdef USE_INSTANCING
+ highp mat4 m = mat4(instance_xform0, instance_xform1, instance_xform2, vec4(0.0, 0.0, 0.0, 1.0));
+ model_matrix = model_matrix * transpose(m);
+#endif
#ifdef NORMAL_USED
vec3 normal = normal_attrib * 2.0 - 1.0;
@@ -209,6 +221,10 @@ void main() {
#if defined(COLOR_USED)
color_interp = color_attrib;
+#ifdef USE_INSTANCING
+ vec4 instance_color = vec4(unpackHalf2x16(instance_color_custom_data.x), unpackHalf2x16(instance_color_custom_data.y));
+ color_interp *= instance_color;
+#endif
#endif
#if defined(UV_USED)
@@ -229,7 +245,11 @@ void main() {
highp mat4 projection_matrix = scene_data.projection_matrix;
highp mat4 inv_projection_matrix = scene_data.inv_projection_matrix;
+#ifdef USE_INSTANCING
+ vec4 instance_custom = vec4(unpackHalf2x16(instance_color_custom_data.z), unpackHalf2x16(instance_color_custom_data.w));
+#else
vec4 instance_custom = vec4(0.0);
+#endif
// Using world coordinates
#if !defined(SKIP_TRANSFORM_USED) && defined(VERTEX_WORLD_COORDS_USED)
diff --git a/drivers/gles3/storage/mesh_storage.cpp b/drivers/gles3/storage/mesh_storage.cpp
index 822be25337..5aa82bfcc1 100644
--- a/drivers/gles3/storage/mesh_storage.cpp
+++ b/drivers/gles3/storage/mesh_storage.cpp
@@ -31,6 +31,7 @@
#ifdef GLES3_ENABLED
#include "mesh_storage.h"
+#include "../rasterizer_storage_gles3.h"
#include "material_storage.h"
using namespace GLES3;
@@ -230,6 +231,7 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind
s->lods[i].edge_length = p_surface.lods[i].edge_length;
s->lods[i].index_count = p_surface.lods[i].index_data.size() / (is_index_16 ? 2 : 4);
+ s->lods[i].index_buffer_size = p_surface.lods[i].index_data.size();
}
}
}
@@ -333,48 +335,10 @@ RS::SurfaceData MeshStorage::mesh_get_surface(RID p_mesh, int p_surface) const {
RS::SurfaceData sd;
sd.format = s.format;
- {
- Vector<uint8_t> ret;
- ret.resize(s.vertex_buffer_size);
- glBindBuffer(GL_ARRAY_BUFFER, s.vertex_buffer);
-
-#if defined(__EMSCRIPTEN__)
- {
- uint8_t *w = ret.ptrw();
- glGetBufferSubData(GL_ARRAY_BUFFER, 0, s.vertex_buffer_size, w);
- }
-#else
- void *data = glMapBufferRange(GL_ARRAY_BUFFER, 0, s.vertex_buffer_size, GL_MAP_READ_BIT);
- ERR_FAIL_NULL_V(data, RS::SurfaceData());
- {
- uint8_t *w = ret.ptrw();
- memcpy(w, data, s.vertex_buffer_size);
- }
- glUnmapBuffer(GL_ARRAY_BUFFER);
-#endif
- sd.vertex_data = ret;
- }
+ sd.vertex_data = RasterizerStorageGLES3::buffer_get_data(GL_ARRAY_BUFFER, s.vertex_buffer, s.vertex_buffer_size);
if (s.attribute_buffer != 0) {
- Vector<uint8_t> ret;
- ret.resize(s.attribute_buffer_size);
- glBindBuffer(GL_ARRAY_BUFFER, s.attribute_buffer);
-
-#if defined(__EMSCRIPTEN__)
- {
- uint8_t *w = ret.ptrw();
- glGetBufferSubData(GL_ARRAY_BUFFER, 0, s.attribute_buffer_size, w);
- }
-#else
- void *data = glMapBufferRange(GL_ARRAY_BUFFER, 0, s.attribute_buffer_size, GL_MAP_READ_BIT);
- ERR_FAIL_NULL_V(data, RS::SurfaceData());
- {
- uint8_t *w = ret.ptrw();
- memcpy(w, data, s.attribute_buffer_size);
- }
- glUnmapBuffer(GL_ARRAY_BUFFER);
-#endif
- sd.attribute_data = ret;
+ sd.attribute_data = RasterizerStorageGLES3::buffer_get_data(GL_ARRAY_BUFFER, s.attribute_buffer, s.attribute_buffer_size);
}
sd.vertex_count = s.vertex_count;
@@ -382,33 +346,14 @@ RS::SurfaceData MeshStorage::mesh_get_surface(RID p_mesh, int p_surface) const {
sd.primitive = s.primitive;
if (sd.index_count) {
- Vector<uint8_t> ret;
- ret.resize(s.index_buffer_size);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s.index_buffer);
-
-#if defined(__EMSCRIPTEN__)
- {
- uint8_t *w = ret.ptrw();
- glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, s.index_buffer_size, w);
- }
-#else
- void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, s.index_buffer_size, GL_MAP_READ_BIT);
- ERR_FAIL_NULL_V(data, RS::SurfaceData());
- {
- uint8_t *w = ret.ptrw();
- memcpy(w, data, s.index_buffer_size);
- }
- glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
-#endif
- sd.index_data = ret;
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ sd.index_data = RasterizerStorageGLES3::buffer_get_data(GL_ELEMENT_ARRAY_BUFFER, s.index_buffer, s.index_buffer_size);
}
sd.aabb = s.aabb;
for (uint32_t i = 0; i < s.lod_count; i++) {
RS::SurfaceData::LOD lod;
lod.edge_length = s.lods[i].edge_length;
- //lod.index_data = RD::get_singleton()->buffer_get_data(s.lods[i].index_buffer);
+ lod.index_data = RasterizerStorageGLES3::buffer_get_data(GL_ELEMENT_ARRAY_BUFFER, s.lods[i].index_buffer, s.lods[i].index_buffer_size);
sd.lods.push_back(lod);
}
@@ -723,17 +668,6 @@ void MeshStorage::_mesh_surface_generate_version_for_input_mask(Mesh::Surface::V
for (int i = 0; i < RS::ARRAY_INDEX; i++) {
if (!attribs[i].enabled) {
glDisableVertexAttribArray(i);
- if (s->format & RS::ARRAY_FLAG_USE_2D_VERTICES) {
- if (i == RS::ARRAY_COLOR) {
- glVertexAttrib4f(i, 1, 1, 1, 1);
- } else if (i == RS::ARRAY_TEX_UV) {
- glVertexAttrib2f(i, 1, 1);
- } else if (i == RS::ARRAY_BONES) {
- glVertexAttrib4f(i, 1, 1, 1, 1);
- } else if (i == RS::ARRAY_WEIGHTS) {
- glVertexAttrib4f(i, 1, 1, 1, 1);
- }
- }
continue;
}
if (i <= RS::ARRAY_TANGENT) {
@@ -949,8 +883,8 @@ void MeshStorage::multimesh_allocate_data(RID p_multimesh, int p_instances, RS::
multimesh->uses_colors = p_use_colors;
multimesh->color_offset_cache = p_transform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12;
multimesh->uses_custom_data = p_use_custom_data;
- multimesh->custom_data_offset_cache = multimesh->color_offset_cache + (p_use_colors ? 4 : 0);
- multimesh->stride_cache = multimesh->custom_data_offset_cache + (p_use_custom_data ? 4 : 0);
+ multimesh->custom_data_offset_cache = multimesh->color_offset_cache + (p_use_colors ? 2 : 0);
+ multimesh->stride_cache = multimesh->custom_data_offset_cache + (p_use_custom_data ? 2 : 0);
multimesh->buffer_set = false;
multimesh->data_cache = Vector<float>();
@@ -977,7 +911,7 @@ int MeshStorage::multimesh_get_instance_count(RID p_multimesh) const {
void MeshStorage::multimesh_set_mesh(RID p_multimesh, RID p_mesh) {
MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
ERR_FAIL_COND(!multimesh);
- if (multimesh->mesh == p_mesh) {
+ if (multimesh->mesh == p_mesh || p_mesh.is_null()) {
return;
}
multimesh->mesh = p_mesh;
@@ -990,13 +924,12 @@ void MeshStorage::multimesh_set_mesh(RID p_multimesh, RID p_mesh) {
//we have a data cache, just mark it dirty
_multimesh_mark_all_dirty(multimesh, false, true);
} else if (multimesh->instances) {
- //need to re-create AABB unfortunately, calling this has a penalty
+ // Need to re-create AABB. Unfortunately, calling this has a penalty.
if (multimesh->buffer_set) {
- // TODO add a function to RasterizerStorage to get data from a buffer
- //Vector<uint8_t> buffer = RD::get_singleton()->buffer_get_data(multimesh->buffer);
- //const uint8_t *r = buffer.ptr();
- //const float *data = (const float *)r;
- //_multimesh_re_create_aabb(multimesh, data, multimesh->instances);
+ Vector<uint8_t> buffer = RasterizerStorageGLES3::buffer_get_data(GL_ARRAY_BUFFER, multimesh->buffer, multimesh->instances * multimesh->stride_cache * sizeof(float));
+ const uint8_t *r = buffer.ptr();
+ const float *data = (const float *)r;
+ _multimesh_re_create_aabb(multimesh, data, multimesh->instances);
}
}
@@ -1017,10 +950,11 @@ void MeshStorage::_multimesh_make_local(MultiMesh *multimesh) const {
float *w = multimesh->data_cache.ptrw();
if (multimesh->buffer_set) {
- //Vector<uint8_t> buffer = RD::get_singleton()->buffer_get_data(multimesh->buffer);
+ Vector<uint8_t> buffer = RasterizerStorageGLES3::buffer_get_data(GL_ARRAY_BUFFER, multimesh->buffer, multimesh->instances * multimesh->stride_cache * sizeof(float));
+
{
- // const uint8_t *r = buffer.ptr();
- // memcpy(w, r, buffer.size());
+ const uint8_t *r = buffer.ptr();
+ memcpy(w, r, buffer.size());
}
} else {
memset(w, 0, (size_t)multimesh->instances * multimesh->stride_cache * sizeof(float));
@@ -1186,14 +1120,12 @@ void MeshStorage::multimesh_instance_set_color(RID p_multimesh, int p_index, con
_multimesh_make_local(multimesh);
{
+ // Colors are packed into 2 floats.
float *w = multimesh->data_cache.ptrw();
float *dataptr = w + p_index * multimesh->stride_cache + multimesh->color_offset_cache;
-
- dataptr[0] = p_color.r;
- dataptr[1] = p_color.g;
- dataptr[2] = p_color.b;
- dataptr[3] = p_color.a;
+ uint16_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) };
+ memcpy(dataptr, val, 2 * 4);
}
_multimesh_mark_dirty(multimesh, p_index, false);
@@ -1211,11 +1143,8 @@ void MeshStorage::multimesh_instance_set_custom_data(RID p_multimesh, int p_inde
float *w = multimesh->data_cache.ptrw();
float *dataptr = w + p_index * multimesh->stride_cache + multimesh->custom_data_offset_cache;
-
- dataptr[0] = p_color.r;
- dataptr[1] = p_color.g;
- dataptr[2] = p_color.b;
- dataptr[3] = p_color.a;
+ uint16_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) };
+ memcpy(dataptr, val, 2 * 4);
}
_multimesh_mark_dirty(multimesh, p_index, false);
@@ -1306,11 +1235,12 @@ Color MeshStorage::multimesh_instance_get_color(RID p_multimesh, int p_index) co
const float *r = multimesh->data_cache.ptr();
const float *dataptr = r + p_index * multimesh->stride_cache + multimesh->color_offset_cache;
-
- c.r = dataptr[0];
- c.g = dataptr[1];
- c.b = dataptr[2];
- c.a = dataptr[3];
+ uint16_t raw_data[4];
+ memcpy(raw_data, dataptr, 2 * 4);
+ c.r = Math::half_to_float(raw_data[0]);
+ c.g = Math::half_to_float(raw_data[1]);
+ c.b = Math::half_to_float(raw_data[2]);
+ c.a = Math::half_to_float(raw_data[3]);
}
return c;
@@ -1329,11 +1259,12 @@ Color MeshStorage::multimesh_instance_get_custom_data(RID p_multimesh, int p_ind
const float *r = multimesh->data_cache.ptr();
const float *dataptr = r + p_index * multimesh->stride_cache + multimesh->custom_data_offset_cache;
-
- c.r = dataptr[0];
- c.g = dataptr[1];
- c.b = dataptr[2];
- c.a = dataptr[3];
+ uint16_t raw_data[4];
+ memcpy(raw_data, dataptr, 2 * 4);
+ c.r = Math::half_to_float(raw_data[0]);
+ c.g = Math::half_to_float(raw_data[1]);
+ c.b = Math::half_to_float(raw_data[2]);
+ c.a = Math::half_to_float(raw_data[3]);
}
return c;
@@ -1342,19 +1273,66 @@ Color MeshStorage::multimesh_instance_get_custom_data(RID p_multimesh, int p_ind
void MeshStorage::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_buffer) {
MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
ERR_FAIL_COND(!multimesh);
- ERR_FAIL_COND(p_buffer.size() != (multimesh->instances * (int)multimesh->stride_cache));
- {
+ if (multimesh->uses_colors || multimesh->uses_custom_data) {
+ // Color and custom need to be packed so copy buffer to data_cache and pack.
+
+ _multimesh_make_local(multimesh);
+ multimesh->data_cache = p_buffer;
+
+ float *w = multimesh->data_cache.ptrw();
+ uint32_t old_stride = multimesh->xform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12;
+ old_stride += multimesh->uses_colors ? 4 : 0;
+ old_stride += multimesh->uses_custom_data ? 4 : 0;
+ for (int i = 0; i < multimesh->instances; i++) {
+ {
+ float *dataptr = w + i * old_stride;
+ float *newptr = w + i * multimesh->stride_cache;
+ float vals[8] = { dataptr[0], dataptr[1], dataptr[2], dataptr[3], dataptr[4], dataptr[5], dataptr[6], dataptr[7] };
+ memcpy(newptr, vals, 8 * 4);
+ }
+
+ if (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_3D) {
+ float *dataptr = w + i * old_stride + 8;
+ float *newptr = w + i * multimesh->stride_cache + 8;
+ float vals[8] = { dataptr[0], dataptr[1], dataptr[2], dataptr[3] };
+ memcpy(newptr, vals, 4 * 4);
+ }
+
+ if (multimesh->uses_colors) {
+ float *dataptr = w + i * old_stride + (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12);
+ float *newptr = w + i * multimesh->stride_cache + multimesh->color_offset_cache;
+ uint16_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]) };
+ memcpy(newptr, val, 2 * 4);
+ }
+ if (multimesh->uses_custom_data) {
+ float *dataptr = w + i * old_stride + (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12) + (multimesh->uses_colors ? 4 : 0);
+ float *newptr = w + i * multimesh->stride_cache + multimesh->custom_data_offset_cache;
+ uint16_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]) };
+ memcpy(newptr, val, 2 * 4);
+ }
+ }
+
+ multimesh->data_cache.resize(multimesh->instances * (int)multimesh->stride_cache);
+ const float *r = multimesh->data_cache.ptr();
+ glBindBuffer(GL_ARRAY_BUFFER, multimesh->buffer);
+ glBufferData(GL_ARRAY_BUFFER, multimesh->data_cache.size() * sizeof(float), r, GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ } else {
+ // Only Transform is being used, so we can upload directly.
+ ERR_FAIL_COND(p_buffer.size() != (multimesh->instances * (int)multimesh->stride_cache));
const float *r = p_buffer.ptr();
glBindBuffer(GL_ARRAY_BUFFER, multimesh->buffer);
glBufferData(GL_ARRAY_BUFFER, p_buffer.size() * sizeof(float), r, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
- multimesh->buffer_set = true;
}
- if (multimesh->data_cache.size()) {
+ multimesh->buffer_set = true;
+
+ if (multimesh->data_cache.size() || multimesh->uses_colors || multimesh->uses_custom_data) {
//if we have a data cache, just update it
- multimesh->data_cache = p_buffer;
+ multimesh->data_cache = multimesh->data_cache;
{
//clear dirty since nothing will be dirty anymore
uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1;
@@ -1367,7 +1345,7 @@ void MeshStorage::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_b
_multimesh_mark_all_dirty(multimesh, false, true); //update AABB
} else if (multimesh->mesh.is_valid()) {
//if we have a mesh set, we need to re-generate the AABB from the new data
- const float *data = p_buffer.ptr();
+ const float *data = multimesh->data_cache.ptr();
_multimesh_re_create_aabb(multimesh, data, multimesh->instances);
multimesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
@@ -1377,22 +1355,71 @@ void MeshStorage::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_b
Vector<float> MeshStorage::multimesh_get_buffer(RID p_multimesh) const {
MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
ERR_FAIL_COND_V(!multimesh, Vector<float>());
+ Vector<float> ret;
if (multimesh->buffer == 0) {
return Vector<float>();
} else if (multimesh->data_cache.size()) {
- return multimesh->data_cache;
+ ret = multimesh->data_cache;
} else {
- //get from memory
+ // Buffer not cached, so fetch from GPU memory. This can be a stalling operation, avoid whenever possible.
- //Vector<uint8_t> buffer = RD::get_singleton()->buffer_get_data(multimesh->buffer);
- Vector<float> ret;
+ Vector<uint8_t> buffer = RasterizerStorageGLES3::buffer_get_data(GL_ARRAY_BUFFER, multimesh->buffer, multimesh->instances * multimesh->stride_cache * sizeof(float));
ret.resize(multimesh->instances * multimesh->stride_cache);
- //{
- // float *w = ret.ptrw();
- // const uint8_t *r = buffer.ptr();
- // memcpy(w, r, buffer.size());
- //}
+ {
+ float *w = ret.ptrw();
+ const uint8_t *r = buffer.ptr();
+ memcpy(w, r, buffer.size());
+ }
+ }
+ if (multimesh->uses_colors || multimesh->uses_custom_data) {
+ // Need to decompress buffer.
+ uint32_t new_stride = multimesh->xform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12;
+ new_stride += multimesh->uses_colors ? 4 : 0;
+ new_stride += multimesh->uses_custom_data ? 4 : 0;
+
+ Vector<float> decompressed;
+ decompressed.resize(multimesh->instances * (int)new_stride);
+ float *w = decompressed.ptrw();
+ const float *r = ret.ptr();
+ for (int i = 0; i < multimesh->instances; i++) {
+ {
+ float *newptr = w + i * new_stride;
+ const float *oldptr = r + i * multimesh->stride_cache;
+ float vals[8] = { oldptr[0], oldptr[1], oldptr[2], oldptr[3], oldptr[4], oldptr[5], oldptr[6], oldptr[7] };
+ memcpy(newptr, vals, 8 * 4);
+ }
+
+ if (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_3D) {
+ float *newptr = w + i * new_stride + 8;
+ const float *oldptr = r + i * multimesh->stride_cache + 8;
+ float vals[8] = { oldptr[0], oldptr[1], oldptr[2], oldptr[3] };
+ memcpy(newptr, vals, 4 * 4);
+ }
+
+ if (multimesh->uses_colors) {
+ float *newptr = w + i * new_stride + (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12);
+ const float *oldptr = r + i * multimesh->stride_cache + multimesh->color_offset_cache;
+ uint16_t raw_data[4];
+ memcpy(raw_data, oldptr, 2 * 4);
+ newptr[0] = Math::half_to_float(raw_data[0]);
+ newptr[1] = Math::half_to_float(raw_data[1]);
+ newptr[2] = Math::half_to_float(raw_data[2]);
+ newptr[3] = Math::half_to_float(raw_data[3]);
+ }
+ if (multimesh->uses_custom_data) {
+ float *newptr = w + i * new_stride + (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12) + (multimesh->uses_colors ? 4 : 0);
+ const float *oldptr = r + i * multimesh->stride_cache + multimesh->custom_data_offset_cache;
+ uint16_t raw_data[4];
+ memcpy(raw_data, oldptr, 2 * 4);
+ newptr[0] = Math::half_to_float(raw_data[0]);
+ newptr[1] = Math::half_to_float(raw_data[1]);
+ newptr[2] = Math::half_to_float(raw_data[2]);
+ newptr[3] = Math::half_to_float(raw_data[3]);
+ }
+ }
+ return decompressed;
+ } else {
return ret;
}
}
@@ -1439,7 +1466,7 @@ void MeshStorage::_update_dirty_multimeshes() {
if (multimesh->data_cache_used_dirty_regions > 32 || multimesh->data_cache_used_dirty_regions > visible_region_count / 2) {
// If there too many dirty regions, or represent the majority of regions, just copy all, else transfer cost piles up too much
glBindBuffer(GL_ARRAY_BUFFER, multimesh->buffer);
- glBufferData(GL_ARRAY_BUFFER, MIN(visible_region_count * region_size, multimesh->instances * (uint32_t)multimesh->stride_cache * (uint32_t)sizeof(float)), data, GL_STATIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, MIN(visible_region_count * region_size, multimesh->instances * multimesh->stride_cache * sizeof(float)), data, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
} else {
// Not that many regions? update them all
@@ -1463,8 +1490,7 @@ void MeshStorage::_update_dirty_multimeshes() {
multimesh->data_cache_used_dirty_regions = 0;
}
- if (multimesh->aabb_dirty) {
- //aabb is dirty..
+ if (multimesh->aabb_dirty && multimesh->mesh.is_valid()) {
_multimesh_re_create_aabb(multimesh, data, visible_instances);
multimesh->aabb_dirty = false;
multimesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
diff --git a/drivers/gles3/storage/mesh_storage.h b/drivers/gles3/storage/mesh_storage.h
index 068aa2fe40..3bb7061413 100644
--- a/drivers/gles3/storage/mesh_storage.h
+++ b/drivers/gles3/storage/mesh_storage.h
@@ -90,6 +90,7 @@ struct Mesh {
struct LOD {
float edge_length = 0.0;
uint32_t index_count = 0;
+ uint32_t index_buffer_size = 0;
GLuint index_buffer;
};
diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp
index f42af0492f..d8d3bacb19 100644
--- a/modules/openxr/openxr_api.cpp
+++ b/modules/openxr/openxr_api.cpp
@@ -1102,7 +1102,7 @@ Size2 OpenXRAPI::get_recommended_target_size() {
return target_size;
}
-XRPose::TrackingConfidence OpenXRAPI::get_head_center(Transform3D &r_transform, Vector3 &r_linear_velocity, const Vector3 &r_angular_velocity) {
+XRPose::TrackingConfidence OpenXRAPI::get_head_center(Transform3D &r_transform, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity) {
XrResult result;
ERR_FAIL_COND_V(!running, XRPose::XR_TRACKING_CONFIDENCE_NONE);
@@ -1730,7 +1730,7 @@ XRPose::TrackingConfidence OpenXRAPI::transform_from_location(const XrHandJointL
return _transform_from_location(p_location, r_transform);
}
-void OpenXRAPI::parse_velocities(const XrSpaceVelocity &p_velocity, Vector3 &r_linear_velocity, Vector3 r_angular_velocity) {
+void OpenXRAPI::parse_velocities(const XrSpaceVelocity &p_velocity, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity) {
if (p_velocity.velocityFlags & XR_SPACE_VELOCITY_LINEAR_VALID_BIT) {
XrVector3f linear_velocity = p_velocity.linearVelocity;
r_linear_velocity = Vector3(linear_velocity.x, linear_velocity.y, linear_velocity.z);
@@ -2303,7 +2303,7 @@ Vector2 OpenXRAPI::get_action_vector2(RID p_action, RID p_tracker) {
return result_state.isActive ? Vector2(result_state.currentState.x, result_state.currentState.y) : Vector2();
}
-XRPose::TrackingConfidence OpenXRAPI::get_action_pose(RID p_action, RID p_tracker, Transform3D &r_transform, Vector3 &r_linear_velocity, const Vector3 &r_angular_velocity) {
+XRPose::TrackingConfidence OpenXRAPI::get_action_pose(RID p_action, RID p_tracker, Transform3D &r_transform, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity) {
ERR_FAIL_COND_V(session == XR_NULL_HANDLE, XRPose::XR_TRACKING_CONFIDENCE_NONE);
Action *action = action_owner.get_or_null(p_action);
ERR_FAIL_NULL_V(action, XRPose::XR_TRACKING_CONFIDENCE_NONE);
diff --git a/modules/openxr/openxr_api.h b/modules/openxr/openxr_api.h
index bd71f0e1c2..fe9e2937b2 100644
--- a/modules/openxr/openxr_api.h
+++ b/modules/openxr/openxr_api.h
@@ -225,7 +225,7 @@ protected:
// helper method to get a valid Transform3D from an openxr space location
XRPose::TrackingConfidence transform_from_location(const XrSpaceLocation &p_location, Transform3D &r_transform);
XRPose::TrackingConfidence transform_from_location(const XrHandJointLocationEXT &p_location, Transform3D &r_transform);
- void parse_velocities(const XrSpaceVelocity &p_velocity, Vector3 &r_linear_velocity, Vector3 r_angular_velocity);
+ void parse_velocities(const XrSpaceVelocity &p_velocity, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity);
public:
static bool openxr_is_enabled(bool p_check_run_in_editor = true);
@@ -247,7 +247,7 @@ public:
bool can_render() { return instance != XR_NULL_HANDLE && session != XR_NULL_HANDLE && running && view_pose_valid && frame_state.shouldRender; };
Size2 get_recommended_target_size();
- XRPose::TrackingConfidence get_head_center(Transform3D &r_transform, Vector3 &r_linear_velocity, const Vector3 &r_angular_velocity);
+ XRPose::TrackingConfidence get_head_center(Transform3D &r_transform, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity);
bool get_view_transform(uint32_t p_view, Transform3D &r_transform);
bool get_view_projection(uint32_t p_view, double p_z_near, double p_z_far, CameraMatrix &p_camera_matrix);
bool process();
@@ -285,7 +285,7 @@ public:
bool get_action_bool(RID p_action, RID p_tracker);
float get_action_float(RID p_action, RID p_tracker);
Vector2 get_action_vector2(RID p_action, RID p_tracker);
- XRPose::TrackingConfidence get_action_pose(RID p_action, RID p_tracker, Transform3D &r_transform, Vector3 &r_linear_velocity, const Vector3 &r_angular_velocity);
+ XRPose::TrackingConfidence get_action_pose(RID p_action, RID p_tracker, Transform3D &r_transform, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity);
bool trigger_haptic_pulse(RID p_action, RID p_tracker, float p_frequency, float p_amplitude, XrDuration p_duration_ns);
OpenXRAPI();
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp
index f7d6ce87dc..86687357d6 100644
--- a/modules/text_server_adv/text_server_adv.cpp
+++ b/modules/text_server_adv/text_server_adv.cpp
@@ -2852,7 +2852,7 @@ Vector2 TextServerAdvanced::font_get_kerning(const RID &p_font_rid, int64_t p_si
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Vector2());
- const HashMap<Vector2i, Vector2, VariantHasher, VariantComparator> &kern = fd->cache[size]->kerning_map;
+ const HashMap<Vector2i, Vector2> &kern = fd->cache[size]->kerning_map;
if (kern.has(p_glyph_pair)) {
if (fd->msdf) {
diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h
index c72454d0bb..e7690cb70d 100644
--- a/modules/text_server_adv/text_server_adv.h
+++ b/modules/text_server_adv/text_server_adv.h
@@ -191,7 +191,7 @@ class TextServerAdvanced : public TextServerExtension {
Vector<FontTexture> textures;
HashMap<int32_t, FontGlyph> glyph_map;
- HashMap<Vector2i, Vector2, VariantHasher, VariantComparator> kerning_map;
+ HashMap<Vector2i, Vector2> kerning_map;
hb_font_t *hb_handle = nullptr;
#ifdef MODULE_FREETYPE_ENABLED
diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp
index 1863baf769..0bece4e7a7 100644
--- a/modules/text_server_fb/text_server_fb.cpp
+++ b/modules/text_server_fb/text_server_fb.cpp
@@ -2000,7 +2000,7 @@ Vector2 TextServerFallback::font_get_kerning(const RID &p_font_rid, int64_t p_si
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Vector2());
- const HashMap<Vector2i, Vector2, VariantHasher, VariantComparator> &kern = fd->cache[size]->kerning_map;
+ const HashMap<Vector2i, Vector2> &kern = fd->cache[size]->kerning_map;
if (kern.has(p_glyph_pair)) {
if (fd->msdf) {
diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h
index c085b58898..e4c81aed5b 100644
--- a/modules/text_server_fb/text_server_fb.h
+++ b/modules/text_server_fb/text_server_fb.h
@@ -159,7 +159,7 @@ class TextServerFallback : public TextServerExtension {
Vector<FontTexture> textures;
HashMap<int32_t, FontGlyph> glyph_map;
- HashMap<Vector2i, Vector2, VariantHasher, VariantComparator> kerning_map;
+ HashMap<Vector2i, Vector2> kerning_map;
#ifdef MODULE_FREETYPE_ENABLED
FT_Face face = nullptr;