mirror of
https://github.com/godotengine/godot
synced 2024-09-05 05:28:27 +00:00
Merge pull request #74937 from bitsawer/fix_uniform_storage
Fix shader uniform storage conversions and crash
This commit is contained in:
commit
166643df32
|
@ -39,32 +39,24 @@
|
|||
|
||||
#include "drivers/gles3/rasterizer_canvas_gles3.h"
|
||||
#include "drivers/gles3/rasterizer_gles3.h"
|
||||
#include "servers/rendering/storage/variant_converters.h"
|
||||
|
||||
using namespace GLES3;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// UBI helper functions
|
||||
|
||||
_FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataType type, int p_array_size, const Variant &value, uint8_t *data) {
|
||||
static void _fill_std140_variant_ubo_value(ShaderLanguage::DataType type, int p_array_size, const Variant &value, uint8_t *data) {
|
||||
switch (type) {
|
||||
case ShaderLanguage::TYPE_BOOL: {
|
||||
uint32_t *gui = (uint32_t *)data;
|
||||
|
||||
if (p_array_size > 0) {
|
||||
const PackedInt32Array &ba = value;
|
||||
int s = ba.size();
|
||||
const int *r = ba.ptr();
|
||||
|
||||
for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
|
||||
if (i < s) {
|
||||
gui[j] = (r[i] != 0) ? 1 : 0;
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
}
|
||||
gui[j + 1] = 0; // ignored
|
||||
gui[j + 2] = 0; // ignored
|
||||
gui[j + 3] = 0; // ignored
|
||||
PackedInt32Array ba = value;
|
||||
for (int i = 0; i < ba.size(); i++) {
|
||||
ba.set(i, ba[i] ? 1 : 0);
|
||||
}
|
||||
write_array_std140<int32_t>(ba, gui, p_array_size, 4);
|
||||
} else {
|
||||
bool v = value;
|
||||
gui[0] = v ? 1 : 0;
|
||||
|
@ -74,22 +66,11 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
uint32_t *gui = (uint32_t *)data;
|
||||
|
||||
if (p_array_size > 0) {
|
||||
const PackedInt32Array &ba = value;
|
||||
int s = ba.size();
|
||||
const int *r = ba.ptr();
|
||||
int count = 2 * p_array_size;
|
||||
|
||||
for (int i = 0, j = 0; i < count; i += 2, j += 4) {
|
||||
if (i < s) {
|
||||
gui[j] = r[i] ? 1 : 0;
|
||||
gui[j + 1] = r[i + 1] ? 1 : 0;
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
gui[j + 1] = 0;
|
||||
}
|
||||
gui[j + 2] = 0; // ignored
|
||||
gui[j + 3] = 0; // ignored
|
||||
PackedInt32Array ba = convert_array_std140<Vector2i, int32_t>(value);
|
||||
for (int i = 0; i < ba.size(); i++) {
|
||||
ba.set(i, ba[i] ? 1 : 0);
|
||||
}
|
||||
write_array_std140<Vector2i>(ba, gui, p_array_size, 4);
|
||||
} else {
|
||||
uint32_t v = value;
|
||||
gui[0] = v & 1 ? 1 : 0;
|
||||
|
@ -100,23 +81,11 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
uint32_t *gui = (uint32_t *)data;
|
||||
|
||||
if (p_array_size > 0) {
|
||||
const PackedInt32Array &ba = value;
|
||||
int s = ba.size();
|
||||
const int *r = ba.ptr();
|
||||
int count = 3 * p_array_size;
|
||||
|
||||
for (int i = 0, j = 0; i < count; i += 3, j += 4) {
|
||||
if (i < s) {
|
||||
gui[j] = r[i] ? 1 : 0;
|
||||
gui[j + 1] = r[i + 1] ? 1 : 0;
|
||||
gui[j + 2] = r[i + 2] ? 1 : 0;
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
gui[j + 1] = 0;
|
||||
gui[j + 2] = 0;
|
||||
}
|
||||
gui[j + 3] = 0; // ignored
|
||||
PackedInt32Array ba = convert_array_std140<Vector3i, int32_t>(value);
|
||||
for (int i = 0; i < ba.size(); i++) {
|
||||
ba.set(i, ba[i] ? 1 : 0);
|
||||
}
|
||||
write_array_std140<Vector3i>(ba, gui, p_array_size, 4);
|
||||
} else {
|
||||
uint32_t v = value;
|
||||
gui[0] = (v & 1) ? 1 : 0;
|
||||
|
@ -128,24 +97,11 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
uint32_t *gui = (uint32_t *)data;
|
||||
|
||||
if (p_array_size > 0) {
|
||||
const PackedInt32Array &ba = value;
|
||||
int s = ba.size();
|
||||
const int *r = ba.ptr();
|
||||
int count = 4 * p_array_size;
|
||||
|
||||
for (int i = 0; i < count; i += 4) {
|
||||
if (i < s) {
|
||||
gui[i] = r[i] ? 1 : 0;
|
||||
gui[i + 1] = r[i + 1] ? 1 : 0;
|
||||
gui[i + 2] = r[i + 2] ? 1 : 0;
|
||||
gui[i + 3] = r[i + 3] ? 1 : 0;
|
||||
} else {
|
||||
gui[i] = 0;
|
||||
gui[i + 1] = 0;
|
||||
gui[i + 2] = 0;
|
||||
gui[i + 3] = 0;
|
||||
}
|
||||
PackedInt32Array ba = convert_array_std140<Vector4i, int32_t>(value);
|
||||
for (int i = 0; i < ba.size(); i++) {
|
||||
ba.set(i, ba[i] ? 1 : 0);
|
||||
}
|
||||
write_array_std140<Vector4i>(ba, gui, p_array_size, 4);
|
||||
} else {
|
||||
uint32_t v = value;
|
||||
gui[0] = (v & 1) ? 1 : 0;
|
||||
|
@ -158,20 +114,8 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
int32_t *gui = (int32_t *)data;
|
||||
|
||||
if (p_array_size > 0) {
|
||||
Vector<int> iv = value;
|
||||
int s = iv.size();
|
||||
const int *r = iv.ptr();
|
||||
|
||||
for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
|
||||
if (i < s) {
|
||||
gui[j] = r[i];
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
}
|
||||
gui[j + 1] = 0; // ignored
|
||||
gui[j + 2] = 0; // ignored
|
||||
gui[j + 3] = 0; // ignored
|
||||
}
|
||||
const PackedInt32Array &iv = value;
|
||||
write_array_std140<int32_t>(iv, gui, p_array_size, 4);
|
||||
} else {
|
||||
int v = value;
|
||||
gui[0] = v;
|
||||
|
@ -179,25 +123,12 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
} break;
|
||||
case ShaderLanguage::TYPE_IVEC2: {
|
||||
int32_t *gui = (int32_t *)data;
|
||||
if (p_array_size > 0) {
|
||||
Vector<int> iv = value;
|
||||
int s = iv.size();
|
||||
int count = 2 * p_array_size;
|
||||
|
||||
const int *r = iv.ptr();
|
||||
for (int i = 0, j = 0; i < count; i += 2, j += 4) {
|
||||
if (i < s) {
|
||||
gui[j] = r[i];
|
||||
gui[j + 1] = r[i + 1];
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
gui[j + 1] = 0;
|
||||
}
|
||||
gui[j + 2] = 0; // ignored
|
||||
gui[j + 3] = 0; // ignored
|
||||
}
|
||||
if (p_array_size > 0) {
|
||||
const PackedInt32Array &iv = convert_array_std140<Vector2i, int32_t>(value);
|
||||
write_array_std140<Vector2i>(iv, gui, p_array_size, 4);
|
||||
} else {
|
||||
Vector2i v = value;
|
||||
Vector2i v = convert_to_vector<Vector2i>(value);
|
||||
gui[0] = v.x;
|
||||
gui[1] = v.y;
|
||||
}
|
||||
|
@ -206,25 +137,10 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
int32_t *gui = (int32_t *)data;
|
||||
|
||||
if (p_array_size > 0) {
|
||||
Vector<int> iv = value;
|
||||
int s = iv.size();
|
||||
int count = 3 * p_array_size;
|
||||
|
||||
const int *r = iv.ptr();
|
||||
for (int i = 0, j = 0; i < count; i += 3, j += 4) {
|
||||
if (i < s) {
|
||||
gui[j] = r[i];
|
||||
gui[j + 1] = r[i + 1];
|
||||
gui[j + 2] = r[i + 2];
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
gui[j + 1] = 0;
|
||||
gui[j + 2] = 0;
|
||||
}
|
||||
gui[j + 3] = 0; // ignored
|
||||
}
|
||||
const PackedInt32Array &iv = convert_array_std140<Vector3i, int32_t>(value);
|
||||
write_array_std140<Vector3i>(iv, gui, p_array_size, 4);
|
||||
} else {
|
||||
Vector3i v = value;
|
||||
Vector3i v = convert_to_vector<Vector3i>(value);
|
||||
gui[0] = v.x;
|
||||
gui[1] = v.y;
|
||||
gui[2] = v.z;
|
||||
|
@ -234,26 +150,10 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
int32_t *gui = (int32_t *)data;
|
||||
|
||||
if (p_array_size > 0) {
|
||||
Vector<int> iv = value;
|
||||
int s = iv.size();
|
||||
int count = 4 * p_array_size;
|
||||
|
||||
const int *r = iv.ptr();
|
||||
for (int i = 0; i < count; i += 4) {
|
||||
if (i < s) {
|
||||
gui[i] = r[i];
|
||||
gui[i + 1] = r[i + 1];
|
||||
gui[i + 2] = r[i + 2];
|
||||
gui[i + 3] = r[i + 3];
|
||||
} else {
|
||||
gui[i] = 0;
|
||||
gui[i + 1] = 0;
|
||||
gui[i + 2] = 0;
|
||||
gui[i + 3] = 0;
|
||||
}
|
||||
}
|
||||
const PackedInt32Array &iv = convert_array_std140<Vector4i, int32_t>(value);
|
||||
write_array_std140<Vector4i>(iv, gui, p_array_size, 4);
|
||||
} else {
|
||||
Vector4i v = value;
|
||||
Vector4i v = convert_to_vector<Vector4i>(value);
|
||||
gui[0] = v.x;
|
||||
gui[1] = v.y;
|
||||
gui[2] = v.z;
|
||||
|
@ -264,20 +164,8 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
uint32_t *gui = (uint32_t *)data;
|
||||
|
||||
if (p_array_size > 0) {
|
||||
Vector<int> iv = value;
|
||||
int s = iv.size();
|
||||
const int *r = iv.ptr();
|
||||
|
||||
for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
|
||||
if (i < s) {
|
||||
gui[j] = r[i];
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
}
|
||||
gui[j + 1] = 0; // ignored
|
||||
gui[j + 2] = 0; // ignored
|
||||
gui[j + 3] = 0; // ignored
|
||||
}
|
||||
const PackedInt32Array &iv = value;
|
||||
write_array_std140<uint32_t>(iv, gui, p_array_size, 4);
|
||||
} else {
|
||||
int v = value;
|
||||
gui[0] = v;
|
||||
|
@ -285,25 +173,12 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
} break;
|
||||
case ShaderLanguage::TYPE_UVEC2: {
|
||||
uint32_t *gui = (uint32_t *)data;
|
||||
if (p_array_size > 0) {
|
||||
Vector<int> iv = value;
|
||||
int s = iv.size();
|
||||
int count = 2 * p_array_size;
|
||||
|
||||
const int *r = iv.ptr();
|
||||
for (int i = 0, j = 0; i < count; i += 2, j += 4) {
|
||||
if (i < s) {
|
||||
gui[j] = r[i];
|
||||
gui[j + 1] = r[i + 1];
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
gui[j + 1] = 0;
|
||||
}
|
||||
gui[j + 2] = 0; // ignored
|
||||
gui[j + 3] = 0; // ignored
|
||||
}
|
||||
if (p_array_size > 0) {
|
||||
const PackedInt32Array &iv = convert_array_std140<Vector2i, int32_t>(value);
|
||||
write_array_std140<Vector2i>(iv, gui, p_array_size, 4);
|
||||
} else {
|
||||
Vector2i v = value;
|
||||
Vector2i v = convert_to_vector<Vector2i>(value);
|
||||
gui[0] = v.x;
|
||||
gui[1] = v.y;
|
||||
}
|
||||
|
@ -312,25 +187,10 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
uint32_t *gui = (uint32_t *)data;
|
||||
|
||||
if (p_array_size > 0) {
|
||||
Vector<int> iv = value;
|
||||
int s = iv.size();
|
||||
int count = 3 * p_array_size;
|
||||
|
||||
const int *r = iv.ptr();
|
||||
for (int i = 0, j = 0; i < count; i += 3, j += 4) {
|
||||
if (i < s) {
|
||||
gui[j] = r[i];
|
||||
gui[j + 1] = r[i + 1];
|
||||
gui[j + 2] = r[i + 2];
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
gui[j + 1] = 0;
|
||||
gui[j + 2] = 0;
|
||||
}
|
||||
gui[j + 3] = 0; // ignored
|
||||
}
|
||||
const PackedInt32Array &iv = convert_array_std140<Vector3i, int32_t>(value);
|
||||
write_array_std140<Vector3i>(iv, gui, p_array_size, 4);
|
||||
} else {
|
||||
Vector3i v = value;
|
||||
Vector3i v = convert_to_vector<Vector3i>(value);
|
||||
gui[0] = v.x;
|
||||
gui[1] = v.y;
|
||||
gui[2] = v.z;
|
||||
|
@ -340,26 +200,10 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
uint32_t *gui = (uint32_t *)data;
|
||||
|
||||
if (p_array_size > 0) {
|
||||
Vector<int> iv = value;
|
||||
int s = iv.size();
|
||||
int count = 4 * p_array_size;
|
||||
|
||||
const int *r = iv.ptr();
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (i < s) {
|
||||
gui[i] = r[i];
|
||||
gui[i + 1] = r[i + 1];
|
||||
gui[i + 2] = r[i + 2];
|
||||
gui[i + 3] = r[i + 3];
|
||||
} else {
|
||||
gui[i] = 0;
|
||||
gui[i + 1] = 0;
|
||||
gui[i + 2] = 0;
|
||||
gui[i + 3] = 0;
|
||||
}
|
||||
}
|
||||
const PackedInt32Array &iv = convert_array_std140<Vector4i, int32_t>(value);
|
||||
write_array_std140<Vector4i>(iv, gui, p_array_size, 4);
|
||||
} else {
|
||||
Vector4i v = value;
|
||||
Vector4i v = convert_to_vector<Vector4i>(value);
|
||||
gui[0] = v.x;
|
||||
gui[1] = v.y;
|
||||
gui[2] = v.z;
|
||||
|
@ -371,18 +215,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
|
||||
if (p_array_size > 0) {
|
||||
const PackedFloat32Array &a = value;
|
||||
int s = a.size();
|
||||
|
||||
for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
|
||||
if (i < s) {
|
||||
gui[j] = a[i];
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
}
|
||||
gui[j + 1] = 0; // ignored
|
||||
gui[j + 2] = 0; // ignored
|
||||
gui[j + 3] = 0; // ignored
|
||||
}
|
||||
write_array_std140<float>(a, gui, p_array_size, 4);
|
||||
} else {
|
||||
float v = value;
|
||||
gui[0] = v;
|
||||
|
@ -392,22 +225,10 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
float *gui = (float *)data;
|
||||
|
||||
if (p_array_size > 0) {
|
||||
const PackedVector2Array &a = value;
|
||||
int s = a.size();
|
||||
|
||||
for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
|
||||
if (i < s) {
|
||||
gui[j] = a[i].x;
|
||||
gui[j + 1] = a[i].y;
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
gui[j + 1] = 0;
|
||||
}
|
||||
gui[j + 2] = 0; // ignored
|
||||
gui[j + 3] = 0; // ignored
|
||||
}
|
||||
const PackedFloat32Array &a = convert_array_std140<Vector2, float>(value);
|
||||
write_array_std140<Vector2>(a, gui, p_array_size, 4);
|
||||
} else {
|
||||
Vector2 v = value;
|
||||
Vector2 v = convert_to_vector<Vector2>(value);
|
||||
gui[0] = v.x;
|
||||
gui[1] = v.y;
|
||||
}
|
||||
|
@ -416,133 +237,27 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
float *gui = (float *)data;
|
||||
|
||||
if (p_array_size > 0) {
|
||||
if (value.get_type() == Variant::PACKED_COLOR_ARRAY) {
|
||||
const PackedColorArray &a = value;
|
||||
int s = a.size();
|
||||
|
||||
for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
|
||||
if (i < s) {
|
||||
Color color = a[i];
|
||||
gui[j] = color.r;
|
||||
gui[j + 1] = color.g;
|
||||
gui[j + 2] = color.b;
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
gui[j + 1] = 0;
|
||||
gui[j + 2] = 0;
|
||||
}
|
||||
gui[j + 3] = 0; // ignored
|
||||
}
|
||||
} else {
|
||||
const PackedVector3Array &a = value;
|
||||
int s = a.size();
|
||||
|
||||
for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
|
||||
if (i < s) {
|
||||
gui[j] = a[i].x;
|
||||
gui[j + 1] = a[i].y;
|
||||
gui[j + 2] = a[i].z;
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
gui[j + 1] = 0;
|
||||
gui[j + 2] = 0;
|
||||
}
|
||||
gui[j + 3] = 0; // ignored
|
||||
}
|
||||
}
|
||||
const PackedFloat32Array &a = convert_array_std140<Vector3, float>(value);
|
||||
write_array_std140<Vector3>(a, gui, p_array_size, 4);
|
||||
} else {
|
||||
if (value.get_type() == Variant::COLOR) {
|
||||
Color v = value;
|
||||
|
||||
gui[0] = v.r;
|
||||
gui[1] = v.g;
|
||||
gui[2] = v.b;
|
||||
} else {
|
||||
Vector3 v = value;
|
||||
gui[0] = v.x;
|
||||
gui[1] = v.y;
|
||||
gui[2] = v.z;
|
||||
}
|
||||
Vector3 v = convert_to_vector<Vector3>(value);
|
||||
gui[0] = v.x;
|
||||
gui[1] = v.y;
|
||||
gui[2] = v.z;
|
||||
}
|
||||
} break;
|
||||
case ShaderLanguage::TYPE_VEC4: {
|
||||
float *gui = (float *)data;
|
||||
|
||||
if (p_array_size > 0) {
|
||||
if (value.get_type() == Variant::PACKED_COLOR_ARRAY) {
|
||||
const PackedColorArray &a = value;
|
||||
int s = a.size();
|
||||
|
||||
for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
|
||||
if (i < s) {
|
||||
Color color = a[i];
|
||||
gui[j] = color.r;
|
||||
gui[j + 1] = color.g;
|
||||
gui[j + 2] = color.b;
|
||||
gui[j + 3] = color.a;
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
gui[j + 1] = 0;
|
||||
gui[j + 2] = 0;
|
||||
gui[j + 3] = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const PackedFloat32Array &a = value;
|
||||
int s = a.size();
|
||||
int count = 4 * p_array_size;
|
||||
|
||||
for (int i = 0; i < count; i += 4) {
|
||||
if (i + 3 < s) {
|
||||
gui[i] = a[i];
|
||||
gui[i + 1] = a[i + 1];
|
||||
gui[i + 2] = a[i + 2];
|
||||
gui[i + 3] = a[i + 3];
|
||||
} else {
|
||||
gui[i] = 0;
|
||||
gui[i + 1] = 0;
|
||||
gui[i + 2] = 0;
|
||||
gui[i + 3] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
const PackedFloat32Array &a = convert_array_std140<Vector4, float>(value);
|
||||
write_array_std140<Vector4>(a, gui, p_array_size, 4);
|
||||
} else {
|
||||
if (value.get_type() == Variant::COLOR) {
|
||||
Color v = value;
|
||||
|
||||
gui[0] = v.r;
|
||||
gui[1] = v.g;
|
||||
gui[2] = v.b;
|
||||
gui[3] = v.a;
|
||||
} else if (value.get_type() == Variant::RECT2) {
|
||||
Rect2 v = value;
|
||||
|
||||
gui[0] = v.position.x;
|
||||
gui[1] = v.position.y;
|
||||
gui[2] = v.size.x;
|
||||
gui[3] = v.size.y;
|
||||
} else if (value.get_type() == Variant::QUATERNION) {
|
||||
Quaternion v = value;
|
||||
|
||||
gui[0] = v.x;
|
||||
gui[1] = v.y;
|
||||
gui[2] = v.z;
|
||||
gui[3] = v.w;
|
||||
} else if (value.get_type() == Variant::VECTOR4) {
|
||||
Vector4 v = value;
|
||||
|
||||
gui[0] = v.x;
|
||||
gui[1] = v.y;
|
||||
gui[2] = v.z;
|
||||
gui[3] = v.w;
|
||||
} else {
|
||||
Plane v = value;
|
||||
|
||||
gui[0] = v.normal.x;
|
||||
gui[1] = v.normal.y;
|
||||
gui[2] = v.normal.z;
|
||||
gui[3] = v.d;
|
||||
}
|
||||
Vector4 v = convert_to_vector<Vector4>(value);
|
||||
gui[0] = v.x;
|
||||
gui[1] = v.y;
|
||||
gui[2] = v.z;
|
||||
gui[3] = v.w;
|
||||
}
|
||||
} break;
|
||||
case ShaderLanguage::TYPE_MAT2: {
|
||||
|
@ -590,135 +305,42 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
float *gui = (float *)data;
|
||||
|
||||
if (p_array_size > 0) {
|
||||
const PackedFloat32Array &a = value;
|
||||
int s = a.size();
|
||||
const PackedFloat32Array &a = convert_array_std140<Basis, float>(value);
|
||||
const Basis default_basis;
|
||||
const int s = a.size();
|
||||
|
||||
for (int i = 0, j = 0; i < p_array_size * 9; i += 9, j += 12) {
|
||||
if (i + 8 < s) {
|
||||
gui[j] = a[i];
|
||||
gui[j + 1] = a[i + 1];
|
||||
gui[j + 2] = a[i + 2];
|
||||
gui[j + 3] = 0; // Ignored.
|
||||
|
||||
gui[j + 4] = a[i + 3];
|
||||
gui[j + 5] = a[i + 4];
|
||||
gui[j + 6] = a[i + 5];
|
||||
gui[j + 7] = 0; // Ignored.
|
||||
|
||||
gui[j + 8] = a[i + 6];
|
||||
gui[j + 9] = a[i + 7];
|
||||
gui[j + 10] = a[i + 8];
|
||||
gui[j + 11] = 0; // Ignored.
|
||||
} else {
|
||||
gui[j] = 1;
|
||||
gui[j + 1] = 0;
|
||||
gui[j + 2] = 0;
|
||||
|
||||
gui[j + 4] = 0;
|
||||
gui[j + 5] = 1;
|
||||
gui[j + 6] = 0;
|
||||
|
||||
gui[j + 8] = 0;
|
||||
gui[j + 9] = 0;
|
||||
gui[j + 10] = 1;
|
||||
convert_item_std140(default_basis, gui + j);
|
||||
}
|
||||
gui[j + 3] = 0; // ignored
|
||||
gui[j + 7] = 0; // ignored
|
||||
gui[j + 11] = 0; // ignored
|
||||
}
|
||||
} else {
|
||||
Basis v = value;
|
||||
gui[0] = v.rows[0][0];
|
||||
gui[1] = v.rows[1][0];
|
||||
gui[2] = v.rows[2][0];
|
||||
gui[3] = 0; // ignored
|
||||
|
||||
gui[4] = v.rows[0][1];
|
||||
gui[5] = v.rows[1][1];
|
||||
gui[6] = v.rows[2][1];
|
||||
gui[7] = 0; // ignored
|
||||
|
||||
gui[8] = v.rows[0][2];
|
||||
gui[9] = v.rows[1][2];
|
||||
gui[10] = v.rows[2][2];
|
||||
gui[11] = 0; // ignored
|
||||
convert_item_std140<Basis>(value, gui);
|
||||
}
|
||||
} break;
|
||||
case ShaderLanguage::TYPE_MAT4: {
|
||||
float *gui = (float *)data;
|
||||
|
||||
if (p_array_size > 0) {
|
||||
const PackedFloat32Array &a = value;
|
||||
int s = a.size();
|
||||
|
||||
for (int i = 0; i < p_array_size * 16; i += 16) {
|
||||
if (i + 15 < s) {
|
||||
gui[i] = a[i];
|
||||
gui[i + 1] = a[i + 1];
|
||||
gui[i + 2] = a[i + 2];
|
||||
gui[i + 3] = a[i + 3];
|
||||
|
||||
gui[i + 4] = a[i + 4];
|
||||
gui[i + 5] = a[i + 5];
|
||||
gui[i + 6] = a[i + 6];
|
||||
gui[i + 7] = a[i + 7];
|
||||
|
||||
gui[i + 8] = a[i + 8];
|
||||
gui[i + 9] = a[i + 9];
|
||||
gui[i + 10] = a[i + 10];
|
||||
gui[i + 11] = a[i + 11];
|
||||
|
||||
gui[i + 12] = a[i + 12];
|
||||
gui[i + 13] = a[i + 13];
|
||||
gui[i + 14] = a[i + 14];
|
||||
gui[i + 15] = a[i + 15];
|
||||
} else {
|
||||
gui[i] = 1;
|
||||
gui[i + 1] = 0;
|
||||
gui[i + 2] = 0;
|
||||
gui[i + 3] = 0;
|
||||
|
||||
gui[i + 4] = 0;
|
||||
gui[i + 5] = 1;
|
||||
gui[i + 6] = 0;
|
||||
gui[i + 7] = 0;
|
||||
|
||||
gui[i + 8] = 0;
|
||||
gui[i + 9] = 0;
|
||||
gui[i + 10] = 1;
|
||||
gui[i + 11] = 0;
|
||||
|
||||
gui[i + 12] = 0;
|
||||
gui[i + 13] = 0;
|
||||
gui[i + 14] = 0;
|
||||
gui[i + 15] = 1;
|
||||
}
|
||||
}
|
||||
} else if (value.get_type() == Variant::TRANSFORM3D) {
|
||||
Transform3D v = value;
|
||||
gui[0] = v.basis.rows[0][0];
|
||||
gui[1] = v.basis.rows[1][0];
|
||||
gui[2] = v.basis.rows[2][0];
|
||||
gui[3] = 0;
|
||||
|
||||
gui[4] = v.basis.rows[0][1];
|
||||
gui[5] = v.basis.rows[1][1];
|
||||
gui[6] = v.basis.rows[2][1];
|
||||
gui[7] = 0;
|
||||
|
||||
gui[8] = v.basis.rows[0][2];
|
||||
gui[9] = v.basis.rows[1][2];
|
||||
gui[10] = v.basis.rows[2][2];
|
||||
gui[11] = 0;
|
||||
|
||||
gui[12] = v.origin.x;
|
||||
gui[13] = v.origin.y;
|
||||
gui[14] = v.origin.z;
|
||||
gui[15] = 1;
|
||||
const PackedFloat32Array &a = convert_array_std140<Projection, float>(value);
|
||||
write_array_std140<Projection>(a, gui, p_array_size, 16);
|
||||
} else {
|
||||
Projection v = value;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
gui[i * 4 + j] = v.columns[i][j];
|
||||
}
|
||||
}
|
||||
convert_item_std140<Projection>(value, gui);
|
||||
}
|
||||
} break;
|
||||
default: {
|
||||
|
@ -1943,7 +1565,7 @@ void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS
|
|||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_IVEC2: {
|
||||
GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index];
|
||||
Vector2i v = p_value;
|
||||
Vector2i v = convert_to_vector<Vector2i>(p_value);
|
||||
bv.x = v.x;
|
||||
bv.y = v.y;
|
||||
bv.z = 0;
|
||||
|
@ -1951,7 +1573,7 @@ void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS
|
|||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_IVEC3: {
|
||||
GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index];
|
||||
Vector3i v = p_value;
|
||||
Vector3i v = convert_to_vector<Vector3i>(p_value);
|
||||
bv.x = v.x;
|
||||
bv.y = v.y;
|
||||
bv.z = v.z;
|
||||
|
@ -1959,11 +1581,11 @@ void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS
|
|||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_IVEC4: {
|
||||
GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index];
|
||||
Vector<int32_t> v = p_value;
|
||||
bv.x = v.size() >= 1 ? v[0] : 0;
|
||||
bv.y = v.size() >= 2 ? v[1] : 0;
|
||||
bv.z = v.size() >= 3 ? v[2] : 0;
|
||||
bv.w = v.size() >= 4 ? v[3] : 0;
|
||||
Vector4i v = convert_to_vector<Vector4i>(p_value);
|
||||
bv.x = v.x;
|
||||
bv.y = v.y;
|
||||
bv.z = v.z;
|
||||
bv.w = v.w;
|
||||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_RECT2I: {
|
||||
GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index];
|
||||
|
@ -1983,7 +1605,7 @@ void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS
|
|||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_UVEC2: {
|
||||
GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index];
|
||||
Vector2i v = p_value;
|
||||
Vector2i v = convert_to_vector<Vector2i>(p_value);
|
||||
bv.x = v.x;
|
||||
bv.y = v.y;
|
||||
bv.z = 0;
|
||||
|
@ -1991,7 +1613,7 @@ void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS
|
|||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_UVEC3: {
|
||||
GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index];
|
||||
Vector3i v = p_value;
|
||||
Vector3i v = convert_to_vector<Vector3i>(p_value);
|
||||
bv.x = v.x;
|
||||
bv.y = v.y;
|
||||
bv.z = v.z;
|
||||
|
@ -1999,11 +1621,11 @@ void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS
|
|||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_UVEC4: {
|
||||
GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index];
|
||||
Vector<int32_t> v = p_value;
|
||||
bv.x = v.size() >= 1 ? v[0] : 0;
|
||||
bv.y = v.size() >= 2 ? v[1] : 0;
|
||||
bv.z = v.size() >= 3 ? v[2] : 0;
|
||||
bv.w = v.size() >= 4 ? v[3] : 0;
|
||||
Vector4i v = convert_to_vector<Vector4i>(p_value);
|
||||
bv.x = v.x;
|
||||
bv.y = v.y;
|
||||
bv.z = v.z;
|
||||
bv.w = v.w;
|
||||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_FLOAT: {
|
||||
GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index];
|
||||
|
@ -2015,7 +1637,7 @@ void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS
|
|||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_VEC2: {
|
||||
GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index];
|
||||
Vector2 v = p_value;
|
||||
Vector2 v = convert_to_vector<Vector2>(p_value);
|
||||
bv.x = v.x;
|
||||
bv.y = v.y;
|
||||
bv.z = 0;
|
||||
|
@ -2023,7 +1645,7 @@ void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS
|
|||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_VEC3: {
|
||||
GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index];
|
||||
Vector3 v = p_value;
|
||||
Vector3 v = convert_to_vector<Vector3>(p_value);
|
||||
bv.x = v.x;
|
||||
bv.y = v.y;
|
||||
bv.z = v.z;
|
||||
|
@ -2031,11 +1653,11 @@ void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS
|
|||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_VEC4: {
|
||||
GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index];
|
||||
Plane v = p_value;
|
||||
bv.x = v.normal.x;
|
||||
bv.y = v.normal.y;
|
||||
bv.z = v.normal.z;
|
||||
bv.w = v.d;
|
||||
Vector4 v = convert_to_vector<Vector4>(p_value);
|
||||
bv.x = v.x;
|
||||
bv.y = v.y;
|
||||
bv.z = v.z;
|
||||
bv.w = v.w;
|
||||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_COLOR: {
|
||||
GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index];
|
||||
|
@ -2081,92 +1703,25 @@ void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS
|
|||
case RS::GLOBAL_VAR_TYPE_MAT3: {
|
||||
GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index];
|
||||
Basis v = p_value;
|
||||
bv[0].x = v.rows[0][0];
|
||||
bv[0].y = v.rows[1][0];
|
||||
bv[0].z = v.rows[2][0];
|
||||
bv[0].w = 0;
|
||||
|
||||
bv[1].x = v.rows[0][1];
|
||||
bv[1].y = v.rows[1][1];
|
||||
bv[1].z = v.rows[2][1];
|
||||
bv[1].w = 0;
|
||||
|
||||
bv[2].x = v.rows[0][2];
|
||||
bv[2].y = v.rows[1][2];
|
||||
bv[2].z = v.rows[2][2];
|
||||
bv[2].w = 0;
|
||||
convert_item_std140<Basis>(v, &bv->x);
|
||||
|
||||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_MAT4: {
|
||||
GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index];
|
||||
|
||||
Vector<float> m2 = p_value;
|
||||
if (m2.size() < 16) {
|
||||
m2.resize(16);
|
||||
}
|
||||
|
||||
bv[0].x = m2[0];
|
||||
bv[0].y = m2[1];
|
||||
bv[0].z = m2[2];
|
||||
bv[0].w = m2[3];
|
||||
|
||||
bv[1].x = m2[4];
|
||||
bv[1].y = m2[5];
|
||||
bv[1].z = m2[6];
|
||||
bv[1].w = m2[7];
|
||||
|
||||
bv[2].x = m2[8];
|
||||
bv[2].y = m2[9];
|
||||
bv[2].z = m2[10];
|
||||
bv[2].w = m2[11];
|
||||
|
||||
bv[3].x = m2[12];
|
||||
bv[3].y = m2[13];
|
||||
bv[3].z = m2[14];
|
||||
bv[3].w = m2[15];
|
||||
Projection m = p_value;
|
||||
convert_item_std140<Projection>(m, &bv->x);
|
||||
|
||||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: {
|
||||
GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index];
|
||||
Transform2D v = p_value;
|
||||
bv[0].x = v.columns[0][0];
|
||||
bv[0].y = v.columns[0][1];
|
||||
bv[0].z = 0;
|
||||
bv[0].w = 0;
|
||||
|
||||
bv[1].x = v.columns[1][0];
|
||||
bv[1].y = v.columns[1][1];
|
||||
bv[1].z = 0;
|
||||
bv[1].w = 0;
|
||||
|
||||
bv[2].x = v.columns[2][0];
|
||||
bv[2].y = v.columns[2][1];
|
||||
bv[2].z = 1;
|
||||
bv[2].w = 0;
|
||||
convert_item_std140<Transform2D>(v, &bv->x);
|
||||
|
||||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_TRANSFORM: {
|
||||
GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index];
|
||||
Transform3D v = p_value;
|
||||
bv[0].x = v.basis.rows[0][0];
|
||||
bv[0].y = v.basis.rows[1][0];
|
||||
bv[0].z = v.basis.rows[2][0];
|
||||
bv[0].w = 0;
|
||||
|
||||
bv[1].x = v.basis.rows[0][1];
|
||||
bv[1].y = v.basis.rows[1][1];
|
||||
bv[1].z = v.basis.rows[2][1];
|
||||
bv[1].w = 0;
|
||||
|
||||
bv[2].x = v.basis.rows[0][2];
|
||||
bv[2].y = v.basis.rows[1][2];
|
||||
bv[2].z = v.basis.rows[2][2];
|
||||
bv[2].w = 0;
|
||||
|
||||
bv[3].x = v.origin.x;
|
||||
bv[3].y = v.origin.y;
|
||||
bv[3].z = v.origin.z;
|
||||
bv[3].w = 1;
|
||||
convert_item_std140<Transform3D>(v, &bv->x);
|
||||
|
||||
} break;
|
||||
default: {
|
||||
|
|
|
@ -198,7 +198,7 @@ protected:
|
|||
pinfo.type = Variant::COLOR;
|
||||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_MAT2: {
|
||||
pinfo.type = Variant::PACKED_INT32_ARRAY;
|
||||
pinfo.type = Variant::PACKED_FLOAT32_ARRAY;
|
||||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_MAT3: {
|
||||
pinfo.type = Variant::BASIS;
|
||||
|
@ -271,13 +271,7 @@ static Variant create_var(RS::GlobalShaderParameterType p_type) {
|
|||
return Vector3i();
|
||||
}
|
||||
case RS::GLOBAL_VAR_TYPE_IVEC4: {
|
||||
Vector<int> v4;
|
||||
v4.resize(4);
|
||||
v4.write[0] = 0;
|
||||
v4.write[1] = 0;
|
||||
v4.write[2] = 0;
|
||||
v4.write[3] = 0;
|
||||
return v4;
|
||||
return Vector4i();
|
||||
}
|
||||
case RS::GLOBAL_VAR_TYPE_RECT2I: {
|
||||
return Rect2i();
|
||||
|
@ -292,13 +286,7 @@ static Variant create_var(RS::GlobalShaderParameterType p_type) {
|
|||
return Vector3i();
|
||||
}
|
||||
case RS::GLOBAL_VAR_TYPE_UVEC4: {
|
||||
Vector<int> v4;
|
||||
v4.resize(4);
|
||||
v4.write[0] = 0;
|
||||
v4.write[1] = 0;
|
||||
v4.write[2] = 0;
|
||||
v4.write[3] = 0;
|
||||
return v4;
|
||||
return Vector4i();
|
||||
}
|
||||
case RS::GLOBAL_VAR_TYPE_FLOAT: {
|
||||
return 0.0;
|
||||
|
@ -310,7 +298,7 @@ static Variant create_var(RS::GlobalShaderParameterType p_type) {
|
|||
return Vector3();
|
||||
}
|
||||
case RS::GLOBAL_VAR_TYPE_VEC4: {
|
||||
return Quaternion();
|
||||
return Vector4();
|
||||
}
|
||||
case RS::GLOBAL_VAR_TYPE_RECT2: {
|
||||
return Rect2();
|
||||
|
@ -319,7 +307,7 @@ static Variant create_var(RS::GlobalShaderParameterType p_type) {
|
|||
return Color();
|
||||
}
|
||||
case RS::GLOBAL_VAR_TYPE_MAT2: {
|
||||
Vector<real_t> xform;
|
||||
Vector<float> xform;
|
||||
xform.resize(4);
|
||||
xform.write[0] = 1;
|
||||
xform.write[1] = 0;
|
||||
|
@ -337,29 +325,7 @@ static Variant create_var(RS::GlobalShaderParameterType p_type) {
|
|||
return Transform3D();
|
||||
}
|
||||
case RS::GLOBAL_VAR_TYPE_MAT4: {
|
||||
Vector<real_t> xform;
|
||||
xform.resize(16);
|
||||
xform.write[0] = 1;
|
||||
xform.write[1] = 0;
|
||||
xform.write[2] = 0;
|
||||
xform.write[3] = 0;
|
||||
|
||||
xform.write[4] = 0;
|
||||
xform.write[5] = 1;
|
||||
xform.write[6] = 0;
|
||||
xform.write[7] = 0;
|
||||
|
||||
xform.write[8] = 0;
|
||||
xform.write[9] = 0;
|
||||
xform.write[10] = 1;
|
||||
xform.write[11] = 0;
|
||||
|
||||
xform.write[12] = 0;
|
||||
xform.write[13] = 0;
|
||||
xform.write[14] = 0;
|
||||
xform.write[15] = 1;
|
||||
|
||||
return xform;
|
||||
return Projection();
|
||||
}
|
||||
case RS::GLOBAL_VAR_TYPE_SAMPLER2D: {
|
||||
return "";
|
||||
|
|
|
@ -128,7 +128,7 @@ void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const
|
|||
pinfo.type = Variant::VECTOR3I;
|
||||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_IVEC4: {
|
||||
pinfo.type = Variant::PACKED_INT32_ARRAY;
|
||||
pinfo.type = Variant::VECTOR4I;
|
||||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_RECT2I: {
|
||||
pinfo.type = Variant::RECT2I;
|
||||
|
@ -143,7 +143,7 @@ void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const
|
|||
pinfo.type = Variant::VECTOR3I;
|
||||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_UVEC4: {
|
||||
pinfo.type = Variant::PACKED_INT32_ARRAY;
|
||||
pinfo.type = Variant::VECTOR4I;
|
||||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_FLOAT: {
|
||||
pinfo.type = Variant::FLOAT;
|
||||
|
@ -164,7 +164,7 @@ void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const
|
|||
pinfo.type = Variant::COLOR;
|
||||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_MAT2: {
|
||||
pinfo.type = Variant::PACKED_INT32_ARRAY;
|
||||
pinfo.type = Variant::PACKED_FLOAT32_ARRAY;
|
||||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_MAT3: {
|
||||
pinfo.type = Variant::BASIS;
|
||||
|
|
|
@ -310,10 +310,34 @@ void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const {
|
|||
vgroups.push_back(Pair<String, LocalVector<String>>("<None>", { "<None>" }));
|
||||
}
|
||||
|
||||
const bool is_uniform_cached = param_cache.has(E->get().name);
|
||||
bool is_uniform_type_compatible = true;
|
||||
|
||||
if (is_uniform_cached) {
|
||||
// Check if the uniform Variant type changed, for example vec3 to vec4.
|
||||
const Variant &cached = param_cache.get(E->get().name);
|
||||
|
||||
if (cached.is_array()) {
|
||||
// Allow some array conversions for backwards compatibility.
|
||||
is_uniform_type_compatible = Variant::can_convert(E->get().type, cached.get_type());
|
||||
} else {
|
||||
is_uniform_type_compatible = E->get().type == cached.get_type();
|
||||
}
|
||||
|
||||
if (is_uniform_type_compatible && E->get().type == Variant::OBJECT && cached.get_type() == Variant::OBJECT) {
|
||||
// Check if the Object class (hint string) changed, for example Texture2D sampler to Texture3D.
|
||||
// Allow inheritance, Texture2D type sampler should also accept CompressedTexture2D.
|
||||
Object *cached_obj = cached;
|
||||
if (!cached_obj->is_class(E->get().hint_string)) {
|
||||
is_uniform_type_compatible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PropertyInfo info = E->get();
|
||||
info.name = "shader_parameter/" + info.name;
|
||||
if (!param_cache.has(E->get().name)) {
|
||||
// Property has never been edited, retrieve with default value.
|
||||
if (!is_uniform_cached || !is_uniform_type_compatible) {
|
||||
// Property has never been edited or its type changed, retrieve with default value.
|
||||
Variant default_value = RenderingServer::get_singleton()->shader_get_parameter_default(shader->get_rid(), E->get().name);
|
||||
param_cache.insert(E->get().name, default_value);
|
||||
remap_cache.insert(info.name, E->get().name);
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "core/config/engine.h"
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/io/resource_loader.h"
|
||||
#include "servers/rendering/storage/variant_converters.h"
|
||||
#include "texture_storage.h"
|
||||
|
||||
using namespace RendererRD;
|
||||
|
@ -39,26 +40,17 @@ using namespace RendererRD;
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// UBI helper functions
|
||||
|
||||
_FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataType type, int p_array_size, const Variant &value, uint8_t *data, bool p_linear_color) {
|
||||
static void _fill_std140_variant_ubo_value(ShaderLanguage::DataType type, int p_array_size, const Variant &value, uint8_t *data, bool p_linear_color) {
|
||||
switch (type) {
|
||||
case ShaderLanguage::TYPE_BOOL: {
|
||||
uint32_t *gui = (uint32_t *)data;
|
||||
|
||||
if (p_array_size > 0) {
|
||||
const PackedInt32Array &ba = value;
|
||||
int s = ba.size();
|
||||
const int *r = ba.ptr();
|
||||
|
||||
for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
|
||||
if (i < s) {
|
||||
gui[j] = (r[i] != 0) ? 1 : 0;
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
}
|
||||
gui[j + 1] = 0; // ignored
|
||||
gui[j + 2] = 0; // ignored
|
||||
gui[j + 3] = 0; // ignored
|
||||
PackedInt32Array ba = value;
|
||||
for (int i = 0; i < ba.size(); i++) {
|
||||
ba.set(i, ba[i] ? 1 : 0);
|
||||
}
|
||||
write_array_std140<int32_t>(ba, gui, p_array_size, 4);
|
||||
} else {
|
||||
bool v = value;
|
||||
gui[0] = v ? 1 : 0;
|
||||
|
@ -68,22 +60,11 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
uint32_t *gui = (uint32_t *)data;
|
||||
|
||||
if (p_array_size > 0) {
|
||||
const PackedInt32Array &ba = value;
|
||||
int s = ba.size();
|
||||
const int *r = ba.ptr();
|
||||
int count = 2 * p_array_size;
|
||||
|
||||
for (int i = 0, j = 0; i < count; i += 2, j += 4) {
|
||||
if (i < s) {
|
||||
gui[j] = r[i] ? 1 : 0;
|
||||
gui[j + 1] = r[i + 1] ? 1 : 0;
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
gui[j + 1] = 0;
|
||||
}
|
||||
gui[j + 2] = 0; // ignored
|
||||
gui[j + 3] = 0; // ignored
|
||||
PackedInt32Array ba = convert_array_std140<Vector2i, int32_t>(value);
|
||||
for (int i = 0; i < ba.size(); i++) {
|
||||
ba.set(i, ba[i] ? 1 : 0);
|
||||
}
|
||||
write_array_std140<Vector2i>(ba, gui, p_array_size, 4);
|
||||
} else {
|
||||
uint32_t v = value;
|
||||
gui[0] = v & 1 ? 1 : 0;
|
||||
|
@ -94,23 +75,11 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
uint32_t *gui = (uint32_t *)data;
|
||||
|
||||
if (p_array_size > 0) {
|
||||
const PackedInt32Array &ba = value;
|
||||
int s = ba.size();
|
||||
const int *r = ba.ptr();
|
||||
int count = 3 * p_array_size;
|
||||
|
||||
for (int i = 0, j = 0; i < count; i += 3, j += 4) {
|
||||
if (i < s) {
|
||||
gui[j] = r[i] ? 1 : 0;
|
||||
gui[j + 1] = r[i + 1] ? 1 : 0;
|
||||
gui[j + 2] = r[i + 2] ? 1 : 0;
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
gui[j + 1] = 0;
|
||||
gui[j + 2] = 0;
|
||||
}
|
||||
gui[j + 3] = 0; // ignored
|
||||
PackedInt32Array ba = convert_array_std140<Vector3i, int32_t>(value);
|
||||
for (int i = 0; i < ba.size(); i++) {
|
||||
ba.set(i, ba[i] ? 1 : 0);
|
||||
}
|
||||
write_array_std140<Vector3i>(ba, gui, p_array_size, 4);
|
||||
} else {
|
||||
uint32_t v = value;
|
||||
gui[0] = (v & 1) ? 1 : 0;
|
||||
|
@ -122,24 +91,11 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
uint32_t *gui = (uint32_t *)data;
|
||||
|
||||
if (p_array_size > 0) {
|
||||
const PackedInt32Array &ba = value;
|
||||
int s = ba.size();
|
||||
const int *r = ba.ptr();
|
||||
int count = 4 * p_array_size;
|
||||
|
||||
for (int i = 0; i < count; i += 4) {
|
||||
if (i < s) {
|
||||
gui[i] = r[i] ? 1 : 0;
|
||||
gui[i + 1] = r[i + 1] ? 1 : 0;
|
||||
gui[i + 2] = r[i + 2] ? 1 : 0;
|
||||
gui[i + 3] = r[i + 3] ? 1 : 0;
|
||||
} else {
|
||||
gui[i] = 0;
|
||||
gui[i + 1] = 0;
|
||||
gui[i + 2] = 0;
|
||||
gui[i + 3] = 0;
|
||||
}
|
||||
PackedInt32Array ba = convert_array_std140<Vector4i, int32_t>(value);
|
||||
for (int i = 0; i < ba.size(); i++) {
|
||||
ba.set(i, ba[i] ? 1 : 0);
|
||||
}
|
||||
write_array_std140<Vector4i>(ba, gui, p_array_size, 4);
|
||||
} else {
|
||||
uint32_t v = value;
|
||||
gui[0] = (v & 1) ? 1 : 0;
|
||||
|
@ -152,20 +108,8 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
int32_t *gui = (int32_t *)data;
|
||||
|
||||
if (p_array_size > 0) {
|
||||
Vector<int> iv = value;
|
||||
int s = iv.size();
|
||||
const int *r = iv.ptr();
|
||||
|
||||
for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
|
||||
if (i < s) {
|
||||
gui[j] = r[i];
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
}
|
||||
gui[j + 1] = 0; // ignored
|
||||
gui[j + 2] = 0; // ignored
|
||||
gui[j + 3] = 0; // ignored
|
||||
}
|
||||
const PackedInt32Array &iv = value;
|
||||
write_array_std140<int32_t>(iv, gui, p_array_size, 4);
|
||||
} else {
|
||||
int v = value;
|
||||
gui[0] = v;
|
||||
|
@ -173,51 +117,24 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
} break;
|
||||
case ShaderLanguage::TYPE_IVEC2: {
|
||||
int32_t *gui = (int32_t *)data;
|
||||
if (p_array_size > 0) {
|
||||
Vector<int> iv = value;
|
||||
int s = iv.size();
|
||||
int count = 2 * p_array_size;
|
||||
|
||||
const int *r = iv.ptr();
|
||||
for (int i = 0, j = 0; i < count; i += 2, j += 4) {
|
||||
if (i < s) {
|
||||
gui[j] = r[i];
|
||||
gui[j + 1] = r[i + 1];
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
gui[j + 1] = 0;
|
||||
}
|
||||
gui[j + 2] = 0; // ignored
|
||||
gui[j + 3] = 0; // ignored
|
||||
}
|
||||
if (p_array_size > 0) {
|
||||
const PackedInt32Array &iv = convert_array_std140<Vector2i, int32_t>(value);
|
||||
write_array_std140<Vector2i>(iv, gui, p_array_size, 4);
|
||||
} else {
|
||||
Vector2i v = value;
|
||||
Vector2i v = convert_to_vector<Vector2i>(value);
|
||||
gui[0] = v.x;
|
||||
gui[1] = v.y;
|
||||
}
|
||||
} break;
|
||||
case ShaderLanguage::TYPE_IVEC3: {
|
||||
int32_t *gui = (int32_t *)data;
|
||||
if (p_array_size > 0) {
|
||||
Vector<int> iv = value;
|
||||
int s = iv.size();
|
||||
int count = 3 * p_array_size;
|
||||
|
||||
const int *r = iv.ptr();
|
||||
for (int i = 0, j = 0; i < count; i += 3, j += 4) {
|
||||
if (i < s) {
|
||||
gui[j] = r[i];
|
||||
gui[j + 1] = r[i + 1];
|
||||
gui[j + 2] = r[i + 2];
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
gui[j + 1] = 0;
|
||||
gui[j + 2] = 0;
|
||||
}
|
||||
gui[j + 3] = 0; // ignored
|
||||
}
|
||||
if (p_array_size > 0) {
|
||||
const PackedInt32Array &iv = convert_array_std140<Vector3i, int32_t>(value);
|
||||
write_array_std140<Vector3i>(iv, gui, p_array_size, 4);
|
||||
} else {
|
||||
Vector3i v = value;
|
||||
Vector3i v = convert_to_vector<Vector3i>(value);
|
||||
gui[0] = v.x;
|
||||
gui[1] = v.y;
|
||||
gui[2] = v.z;
|
||||
|
@ -225,27 +142,12 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
} break;
|
||||
case ShaderLanguage::TYPE_IVEC4: {
|
||||
int32_t *gui = (int32_t *)data;
|
||||
if (p_array_size > 0) {
|
||||
Vector<int> iv = value;
|
||||
int s = iv.size();
|
||||
int count = 4 * p_array_size;
|
||||
|
||||
const int *r = iv.ptr();
|
||||
for (int i = 0; i < count; i += 4) {
|
||||
if (i < s) {
|
||||
gui[i] = r[i];
|
||||
gui[i + 1] = r[i + 1];
|
||||
gui[i + 2] = r[i + 2];
|
||||
gui[i + 3] = r[i + 3];
|
||||
} else {
|
||||
gui[i] = 0;
|
||||
gui[i + 1] = 0;
|
||||
gui[i + 2] = 0;
|
||||
gui[i + 3] = 0;
|
||||
}
|
||||
}
|
||||
if (p_array_size > 0) {
|
||||
const PackedInt32Array &iv = convert_array_std140<Vector4i, int32_t>(value);
|
||||
write_array_std140<Vector4i>(iv, gui, p_array_size, 4);
|
||||
} else {
|
||||
Vector4i v = value;
|
||||
Vector4i v = convert_to_vector<Vector4i>(value);
|
||||
gui[0] = v.x;
|
||||
gui[1] = v.y;
|
||||
gui[2] = v.z;
|
||||
|
@ -256,20 +158,8 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
uint32_t *gui = (uint32_t *)data;
|
||||
|
||||
if (p_array_size > 0) {
|
||||
Vector<int> iv = value;
|
||||
int s = iv.size();
|
||||
const int *r = iv.ptr();
|
||||
|
||||
for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
|
||||
if (i < s) {
|
||||
gui[j] = r[i];
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
}
|
||||
gui[j + 1] = 0; // ignored
|
||||
gui[j + 2] = 0; // ignored
|
||||
gui[j + 3] = 0; // ignored
|
||||
}
|
||||
const PackedInt32Array &iv = value;
|
||||
write_array_std140<uint32_t>(iv, gui, p_array_size, 4);
|
||||
} else {
|
||||
int v = value;
|
||||
gui[0] = v;
|
||||
|
@ -277,51 +167,24 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
} break;
|
||||
case ShaderLanguage::TYPE_UVEC2: {
|
||||
uint32_t *gui = (uint32_t *)data;
|
||||
if (p_array_size > 0) {
|
||||
Vector<int> iv = value;
|
||||
int s = iv.size();
|
||||
int count = 2 * p_array_size;
|
||||
|
||||
const int *r = iv.ptr();
|
||||
for (int i = 0, j = 0; i < count; i += 2, j += 4) {
|
||||
if (i < s) {
|
||||
gui[j] = r[i];
|
||||
gui[j + 1] = r[i + 1];
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
gui[j + 1] = 0;
|
||||
}
|
||||
gui[j + 2] = 0; // ignored
|
||||
gui[j + 3] = 0; // ignored
|
||||
}
|
||||
if (p_array_size > 0) {
|
||||
const PackedInt32Array &iv = convert_array_std140<Vector2i, int32_t>(value);
|
||||
write_array_std140<Vector2i>(iv, gui, p_array_size, 4);
|
||||
} else {
|
||||
Vector2i v = value;
|
||||
Vector2i v = convert_to_vector<Vector2i>(value);
|
||||
gui[0] = v.x;
|
||||
gui[1] = v.y;
|
||||
}
|
||||
} break;
|
||||
case ShaderLanguage::TYPE_UVEC3: {
|
||||
uint32_t *gui = (uint32_t *)data;
|
||||
if (p_array_size > 0) {
|
||||
Vector<int> iv = value;
|
||||
int s = iv.size();
|
||||
int count = 3 * p_array_size;
|
||||
|
||||
const int *r = iv.ptr();
|
||||
for (int i = 0, j = 0; i < count; i += 3, j += 4) {
|
||||
if (i < s) {
|
||||
gui[j] = r[i];
|
||||
gui[j + 1] = r[i + 1];
|
||||
gui[j + 2] = r[i + 2];
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
gui[j + 1] = 0;
|
||||
gui[j + 2] = 0;
|
||||
}
|
||||
gui[j + 3] = 0; // ignored
|
||||
}
|
||||
if (p_array_size > 0) {
|
||||
const PackedInt32Array &iv = convert_array_std140<Vector3i, int32_t>(value);
|
||||
write_array_std140<Vector3i>(iv, gui, p_array_size, 4);
|
||||
} else {
|
||||
Vector3i v = value;
|
||||
Vector3i v = convert_to_vector<Vector3i>(value);
|
||||
gui[0] = v.x;
|
||||
gui[1] = v.y;
|
||||
gui[2] = v.z;
|
||||
|
@ -329,27 +192,12 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
} break;
|
||||
case ShaderLanguage::TYPE_UVEC4: {
|
||||
uint32_t *gui = (uint32_t *)data;
|
||||
if (p_array_size > 0) {
|
||||
Vector<int> iv = value;
|
||||
int s = iv.size();
|
||||
int count = 4 * p_array_size;
|
||||
|
||||
const int *r = iv.ptr();
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (i < s) {
|
||||
gui[i] = r[i];
|
||||
gui[i + 1] = r[i + 1];
|
||||
gui[i + 2] = r[i + 2];
|
||||
gui[i + 3] = r[i + 3];
|
||||
} else {
|
||||
gui[i] = 0;
|
||||
gui[i + 1] = 0;
|
||||
gui[i + 2] = 0;
|
||||
gui[i + 3] = 0;
|
||||
}
|
||||
}
|
||||
if (p_array_size > 0) {
|
||||
const PackedInt32Array &iv = convert_array_std140<Vector4i, int32_t>(value);
|
||||
write_array_std140<Vector4i>(iv, gui, p_array_size, 4);
|
||||
} else {
|
||||
Vector4i v = value;
|
||||
Vector4i v = convert_to_vector<Vector4i>(value);
|
||||
gui[0] = v.x;
|
||||
gui[1] = v.y;
|
||||
gui[2] = v.z;
|
||||
|
@ -361,18 +209,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
|
||||
if (p_array_size > 0) {
|
||||
const PackedFloat32Array &a = value;
|
||||
int s = a.size();
|
||||
|
||||
for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
|
||||
if (i < s) {
|
||||
gui[j] = a[i];
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
}
|
||||
gui[j + 1] = 0; // ignored
|
||||
gui[j + 2] = 0; // ignored
|
||||
gui[j + 3] = 0; // ignored
|
||||
}
|
||||
write_array_std140<float>(a, gui, p_array_size, 4);
|
||||
} else {
|
||||
float v = value;
|
||||
gui[0] = v;
|
||||
|
@ -382,22 +219,10 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
float *gui = reinterpret_cast<float *>(data);
|
||||
|
||||
if (p_array_size > 0) {
|
||||
const PackedVector2Array &a = value;
|
||||
int s = a.size();
|
||||
|
||||
for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
|
||||
if (i < s) {
|
||||
gui[j] = a[i].x;
|
||||
gui[j + 1] = a[i].y;
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
gui[j + 1] = 0;
|
||||
}
|
||||
gui[j + 2] = 0; // ignored
|
||||
gui[j + 3] = 0; // ignored
|
||||
}
|
||||
const PackedFloat32Array &a = convert_array_std140<Vector2, float>(value);
|
||||
write_array_std140<Vector2>(a, gui, p_array_size, 4);
|
||||
} else {
|
||||
Vector2 v = value;
|
||||
Vector2 v = convert_to_vector<Vector2>(value);
|
||||
gui[0] = v.x;
|
||||
gui[1] = v.y;
|
||||
}
|
||||
|
@ -406,147 +231,27 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
float *gui = reinterpret_cast<float *>(data);
|
||||
|
||||
if (p_array_size > 0) {
|
||||
if (value.get_type() == Variant::PACKED_COLOR_ARRAY) {
|
||||
const PackedColorArray &a = value;
|
||||
int s = a.size();
|
||||
|
||||
for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
|
||||
if (i < s) {
|
||||
Color color = a[i];
|
||||
if (p_linear_color) {
|
||||
color = color.srgb_to_linear();
|
||||
}
|
||||
gui[j] = color.r;
|
||||
gui[j + 1] = color.g;
|
||||
gui[j + 2] = color.b;
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
gui[j + 1] = 0;
|
||||
gui[j + 2] = 0;
|
||||
}
|
||||
gui[j + 3] = 0; // ignored
|
||||
}
|
||||
} else {
|
||||
const PackedVector3Array &a = value;
|
||||
int s = a.size();
|
||||
|
||||
for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
|
||||
if (i < s) {
|
||||
gui[j] = a[i].x;
|
||||
gui[j + 1] = a[i].y;
|
||||
gui[j + 2] = a[i].z;
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
gui[j + 1] = 0;
|
||||
gui[j + 2] = 0;
|
||||
}
|
||||
gui[j + 3] = 0; // ignored
|
||||
}
|
||||
}
|
||||
const PackedFloat32Array &a = convert_array_std140<Vector3, float>(value, p_linear_color);
|
||||
write_array_std140<Vector3>(a, gui, p_array_size, 4);
|
||||
} else {
|
||||
if (value.get_type() == Variant::COLOR) {
|
||||
Color v = value;
|
||||
|
||||
if (p_linear_color) {
|
||||
v = v.srgb_to_linear();
|
||||
}
|
||||
|
||||
gui[0] = v.r;
|
||||
gui[1] = v.g;
|
||||
gui[2] = v.b;
|
||||
} else {
|
||||
Vector3 v = value;
|
||||
gui[0] = v.x;
|
||||
gui[1] = v.y;
|
||||
gui[2] = v.z;
|
||||
}
|
||||
Vector3 v = convert_to_vector<Vector3>(value, p_linear_color);
|
||||
gui[0] = v.x;
|
||||
gui[1] = v.y;
|
||||
gui[2] = v.z;
|
||||
}
|
||||
} break;
|
||||
case ShaderLanguage::TYPE_VEC4: {
|
||||
float *gui = reinterpret_cast<float *>(data);
|
||||
|
||||
if (p_array_size > 0) {
|
||||
if (value.get_type() == Variant::PACKED_COLOR_ARRAY) {
|
||||
const PackedColorArray &a = value;
|
||||
int s = a.size();
|
||||
|
||||
for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
|
||||
if (i < s) {
|
||||
Color color = a[i];
|
||||
if (p_linear_color) {
|
||||
color = color.srgb_to_linear();
|
||||
}
|
||||
gui[j] = color.r;
|
||||
gui[j + 1] = color.g;
|
||||
gui[j + 2] = color.b;
|
||||
gui[j + 3] = color.a;
|
||||
} else {
|
||||
gui[j] = 0;
|
||||
gui[j + 1] = 0;
|
||||
gui[j + 2] = 0;
|
||||
gui[j + 3] = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const PackedFloat32Array &a = value;
|
||||
int s = a.size();
|
||||
int count = 4 * p_array_size;
|
||||
|
||||
for (int i = 0; i < count; i += 4) {
|
||||
if (i + 3 < s) {
|
||||
gui[i] = a[i];
|
||||
gui[i + 1] = a[i + 1];
|
||||
gui[i + 2] = a[i + 2];
|
||||
gui[i + 3] = a[i + 3];
|
||||
} else {
|
||||
gui[i] = 0;
|
||||
gui[i + 1] = 0;
|
||||
gui[i + 2] = 0;
|
||||
gui[i + 3] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
const PackedFloat32Array &a = convert_array_std140<Vector4, float>(value, p_linear_color);
|
||||
write_array_std140<Vector4>(a, gui, p_array_size, 4);
|
||||
} else {
|
||||
if (value.get_type() == Variant::COLOR) {
|
||||
Color v = value;
|
||||
|
||||
if (p_linear_color) {
|
||||
v = v.srgb_to_linear();
|
||||
}
|
||||
|
||||
gui[0] = v.r;
|
||||
gui[1] = v.g;
|
||||
gui[2] = v.b;
|
||||
gui[3] = v.a;
|
||||
} else if (value.get_type() == Variant::RECT2) {
|
||||
Rect2 v = value;
|
||||
|
||||
gui[0] = v.position.x;
|
||||
gui[1] = v.position.y;
|
||||
gui[2] = v.size.x;
|
||||
gui[3] = v.size.y;
|
||||
} else if (value.get_type() == Variant::QUATERNION) {
|
||||
Quaternion v = value;
|
||||
|
||||
gui[0] = v.x;
|
||||
gui[1] = v.y;
|
||||
gui[2] = v.z;
|
||||
gui[3] = v.w;
|
||||
} else if (value.get_type() == Variant::PLANE) {
|
||||
Plane v = value;
|
||||
|
||||
gui[0] = v.normal.x;
|
||||
gui[1] = v.normal.y;
|
||||
gui[2] = v.normal.z;
|
||||
gui[3] = v.d;
|
||||
} else {
|
||||
Vector4 v = value;
|
||||
|
||||
gui[0] = v.x;
|
||||
gui[1] = v.y;
|
||||
gui[2] = v.z;
|
||||
gui[3] = v.w;
|
||||
}
|
||||
Vector4 v = convert_to_vector<Vector4>(value, p_linear_color);
|
||||
gui[0] = v.x;
|
||||
gui[1] = v.y;
|
||||
gui[2] = v.z;
|
||||
gui[3] = v.w;
|
||||
}
|
||||
} break;
|
||||
case ShaderLanguage::TYPE_MAT2: {
|
||||
|
@ -594,135 +299,42 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|||
float *gui = reinterpret_cast<float *>(data);
|
||||
|
||||
if (p_array_size > 0) {
|
||||
const PackedFloat32Array &a = value;
|
||||
int s = a.size();
|
||||
const PackedFloat32Array &a = convert_array_std140<Basis, float>(value);
|
||||
const Basis default_basis;
|
||||
const int s = a.size();
|
||||
|
||||
for (int i = 0, j = 0; i < p_array_size * 9; i += 9, j += 12) {
|
||||
if (i + 8 < s) {
|
||||
gui[j] = a[i];
|
||||
gui[j + 1] = a[i + 1];
|
||||
gui[j + 2] = a[i + 2];
|
||||
gui[j + 3] = 0; // Ignored.
|
||||
|
||||
gui[j + 4] = a[i + 3];
|
||||
gui[j + 5] = a[i + 4];
|
||||
gui[j + 6] = a[i + 5];
|
||||
gui[j + 7] = 0; // Ignored.
|
||||
|
||||
gui[j + 8] = a[i + 6];
|
||||
gui[j + 9] = a[i + 7];
|
||||
gui[j + 10] = a[i + 8];
|
||||
gui[j + 11] = 0; // Ignored.
|
||||
} else {
|
||||
gui[j] = 1;
|
||||
gui[j + 1] = 0;
|
||||
gui[j + 2] = 0;
|
||||
|
||||
gui[j + 4] = 0;
|
||||
gui[j + 5] = 1;
|
||||
gui[j + 6] = 0;
|
||||
|
||||
gui[j + 8] = 0;
|
||||
gui[j + 9] = 0;
|
||||
gui[j + 10] = 1;
|
||||
convert_item_std140(default_basis, gui + j);
|
||||
}
|
||||
gui[j + 3] = 0; // ignored
|
||||
gui[j + 7] = 0; // ignored
|
||||
gui[j + 11] = 0; // ignored
|
||||
}
|
||||
} else {
|
||||
Basis v = value;
|
||||
gui[0] = v.rows[0][0];
|
||||
gui[1] = v.rows[1][0];
|
||||
gui[2] = v.rows[2][0];
|
||||
gui[3] = 0; // ignored
|
||||
|
||||
gui[4] = v.rows[0][1];
|
||||
gui[5] = v.rows[1][1];
|
||||
gui[6] = v.rows[2][1];
|
||||
gui[7] = 0; // ignored
|
||||
|
||||
gui[8] = v.rows[0][2];
|
||||
gui[9] = v.rows[1][2];
|
||||
gui[10] = v.rows[2][2];
|
||||
gui[11] = 0; // ignored
|
||||
convert_item_std140<Basis>(value, gui);
|
||||
}
|
||||
} break;
|
||||
case ShaderLanguage::TYPE_MAT4: {
|
||||
float *gui = reinterpret_cast<float *>(data);
|
||||
|
||||
if (p_array_size > 0) {
|
||||
const PackedFloat32Array &a = value;
|
||||
int s = a.size();
|
||||
|
||||
for (int i = 0; i < p_array_size * 16; i += 16) {
|
||||
if (i + 15 < s) {
|
||||
gui[i] = a[i];
|
||||
gui[i + 1] = a[i + 1];
|
||||
gui[i + 2] = a[i + 2];
|
||||
gui[i + 3] = a[i + 3];
|
||||
|
||||
gui[i + 4] = a[i + 4];
|
||||
gui[i + 5] = a[i + 5];
|
||||
gui[i + 6] = a[i + 6];
|
||||
gui[i + 7] = a[i + 7];
|
||||
|
||||
gui[i + 8] = a[i + 8];
|
||||
gui[i + 9] = a[i + 9];
|
||||
gui[i + 10] = a[i + 10];
|
||||
gui[i + 11] = a[i + 11];
|
||||
|
||||
gui[i + 12] = a[i + 12];
|
||||
gui[i + 13] = a[i + 13];
|
||||
gui[i + 14] = a[i + 14];
|
||||
gui[i + 15] = a[i + 15];
|
||||
} else {
|
||||
gui[i] = 1;
|
||||
gui[i + 1] = 0;
|
||||
gui[i + 2] = 0;
|
||||
gui[i + 3] = 0;
|
||||
|
||||
gui[i + 4] = 0;
|
||||
gui[i + 5] = 1;
|
||||
gui[i + 6] = 0;
|
||||
gui[i + 7] = 0;
|
||||
|
||||
gui[i + 8] = 0;
|
||||
gui[i + 9] = 0;
|
||||
gui[i + 10] = 1;
|
||||
gui[i + 11] = 0;
|
||||
|
||||
gui[i + 12] = 0;
|
||||
gui[i + 13] = 0;
|
||||
gui[i + 14] = 0;
|
||||
gui[i + 15] = 1;
|
||||
}
|
||||
}
|
||||
} else if (value.get_type() == Variant::TRANSFORM3D) {
|
||||
Transform3D v = value;
|
||||
gui[0] = v.basis.rows[0][0];
|
||||
gui[1] = v.basis.rows[1][0];
|
||||
gui[2] = v.basis.rows[2][0];
|
||||
gui[3] = 0;
|
||||
|
||||
gui[4] = v.basis.rows[0][1];
|
||||
gui[5] = v.basis.rows[1][1];
|
||||
gui[6] = v.basis.rows[2][1];
|
||||
gui[7] = 0;
|
||||
|
||||
gui[8] = v.basis.rows[0][2];
|
||||
gui[9] = v.basis.rows[1][2];
|
||||
gui[10] = v.basis.rows[2][2];
|
||||
gui[11] = 0;
|
||||
|
||||
gui[12] = v.origin.x;
|
||||
gui[13] = v.origin.y;
|
||||
gui[14] = v.origin.z;
|
||||
gui[15] = 1;
|
||||
const PackedFloat32Array &a = convert_array_std140<Projection, float>(value);
|
||||
write_array_std140<Projection>(a, gui, p_array_size, 16);
|
||||
} else {
|
||||
Projection v = value;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
gui[i * 4 + j] = v.columns[i][j];
|
||||
}
|
||||
}
|
||||
convert_item_std140<Projection>(value, gui);
|
||||
}
|
||||
} break;
|
||||
default: {
|
||||
|
@ -1820,7 +1432,7 @@ void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS
|
|||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_IVEC2: {
|
||||
GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index];
|
||||
Vector2i v = p_value;
|
||||
Vector2i v = convert_to_vector<Vector2i>(p_value);
|
||||
bv.x = v.x;
|
||||
bv.y = v.y;
|
||||
bv.z = 0;
|
||||
|
@ -1828,7 +1440,7 @@ void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS
|
|||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_IVEC3: {
|
||||
GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index];
|
||||
Vector3i v = p_value;
|
||||
Vector3i v = convert_to_vector<Vector3i>(p_value);
|
||||
bv.x = v.x;
|
||||
bv.y = v.y;
|
||||
bv.z = v.z;
|
||||
|
@ -1836,11 +1448,11 @@ void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS
|
|||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_IVEC4: {
|
||||
GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index];
|
||||
Vector<int32_t> v = p_value;
|
||||
bv.x = v.size() >= 1 ? v[0] : 0;
|
||||
bv.y = v.size() >= 2 ? v[1] : 0;
|
||||
bv.z = v.size() >= 3 ? v[2] : 0;
|
||||
bv.w = v.size() >= 4 ? v[3] : 0;
|
||||
Vector4i v = convert_to_vector<Vector4i>(p_value);
|
||||
bv.x = v.x;
|
||||
bv.y = v.y;
|
||||
bv.z = v.z;
|
||||
bv.w = v.w;
|
||||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_RECT2I: {
|
||||
GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index];
|
||||
|
@ -1860,7 +1472,7 @@ void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS
|
|||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_UVEC2: {
|
||||
GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index];
|
||||
Vector2i v = p_value;
|
||||
Vector2i v = convert_to_vector<Vector2i>(p_value);
|
||||
bv.x = v.x;
|
||||
bv.y = v.y;
|
||||
bv.z = 0;
|
||||
|
@ -1868,7 +1480,7 @@ void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS
|
|||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_UVEC3: {
|
||||
GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index];
|
||||
Vector3i v = p_value;
|
||||
Vector3i v = convert_to_vector<Vector3i>(p_value);
|
||||
bv.x = v.x;
|
||||
bv.y = v.y;
|
||||
bv.z = v.z;
|
||||
|
@ -1876,11 +1488,11 @@ void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS
|
|||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_UVEC4: {
|
||||
GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index];
|
||||
Vector<int32_t> v = p_value;
|
||||
bv.x = v.size() >= 1 ? v[0] : 0;
|
||||
bv.y = v.size() >= 2 ? v[1] : 0;
|
||||
bv.z = v.size() >= 3 ? v[2] : 0;
|
||||
bv.w = v.size() >= 4 ? v[3] : 0;
|
||||
Vector4i v = convert_to_vector<Vector4i>(p_value);
|
||||
bv.x = v.x;
|
||||
bv.y = v.y;
|
||||
bv.z = v.z;
|
||||
bv.w = v.w;
|
||||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_FLOAT: {
|
||||
GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index];
|
||||
|
@ -1892,7 +1504,7 @@ void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS
|
|||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_VEC2: {
|
||||
GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index];
|
||||
Vector2 v = p_value;
|
||||
Vector2 v = convert_to_vector<Vector2>(p_value);
|
||||
bv.x = v.x;
|
||||
bv.y = v.y;
|
||||
bv.z = 0;
|
||||
|
@ -1900,7 +1512,7 @@ void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS
|
|||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_VEC3: {
|
||||
GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index];
|
||||
Vector3 v = p_value;
|
||||
Vector3 v = convert_to_vector<Vector3>(p_value);
|
||||
bv.x = v.x;
|
||||
bv.y = v.y;
|
||||
bv.z = v.z;
|
||||
|
@ -1908,11 +1520,11 @@ void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS
|
|||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_VEC4: {
|
||||
GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index];
|
||||
Plane v = p_value;
|
||||
bv.x = v.normal.x;
|
||||
bv.y = v.normal.y;
|
||||
bv.z = v.normal.z;
|
||||
bv.w = v.d;
|
||||
Vector4 v = convert_to_vector<Vector4>(p_value);
|
||||
bv.x = v.x;
|
||||
bv.y = v.y;
|
||||
bv.z = v.z;
|
||||
bv.w = v.w;
|
||||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_COLOR: {
|
||||
GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index];
|
||||
|
@ -1958,92 +1570,25 @@ void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS
|
|||
case RS::GLOBAL_VAR_TYPE_MAT3: {
|
||||
GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index];
|
||||
Basis v = p_value;
|
||||
bv[0].x = v.rows[0][0];
|
||||
bv[0].y = v.rows[1][0];
|
||||
bv[0].z = v.rows[2][0];
|
||||
bv[0].w = 0;
|
||||
|
||||
bv[1].x = v.rows[0][1];
|
||||
bv[1].y = v.rows[1][1];
|
||||
bv[1].z = v.rows[2][1];
|
||||
bv[1].w = 0;
|
||||
|
||||
bv[2].x = v.rows[0][2];
|
||||
bv[2].y = v.rows[1][2];
|
||||
bv[2].z = v.rows[2][2];
|
||||
bv[2].w = 0;
|
||||
convert_item_std140<Basis>(v, &bv->x);
|
||||
|
||||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_MAT4: {
|
||||
GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index];
|
||||
|
||||
Vector<float> m2 = p_value;
|
||||
if (m2.size() < 16) {
|
||||
m2.resize(16);
|
||||
}
|
||||
|
||||
bv[0].x = m2[0];
|
||||
bv[0].y = m2[1];
|
||||
bv[0].z = m2[2];
|
||||
bv[0].w = m2[3];
|
||||
|
||||
bv[1].x = m2[4];
|
||||
bv[1].y = m2[5];
|
||||
bv[1].z = m2[6];
|
||||
bv[1].w = m2[7];
|
||||
|
||||
bv[2].x = m2[8];
|
||||
bv[2].y = m2[9];
|
||||
bv[2].z = m2[10];
|
||||
bv[2].w = m2[11];
|
||||
|
||||
bv[3].x = m2[12];
|
||||
bv[3].y = m2[13];
|
||||
bv[3].z = m2[14];
|
||||
bv[3].w = m2[15];
|
||||
Projection m = p_value;
|
||||
convert_item_std140<Projection>(m, &bv->x);
|
||||
|
||||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: {
|
||||
GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index];
|
||||
Transform2D v = p_value;
|
||||
bv[0].x = v.columns[0][0];
|
||||
bv[0].y = v.columns[0][1];
|
||||
bv[0].z = 0;
|
||||
bv[0].w = 0;
|
||||
|
||||
bv[1].x = v.columns[1][0];
|
||||
bv[1].y = v.columns[1][1];
|
||||
bv[1].z = 0;
|
||||
bv[1].w = 0;
|
||||
|
||||
bv[2].x = v.columns[2][0];
|
||||
bv[2].y = v.columns[2][1];
|
||||
bv[2].z = 1;
|
||||
bv[2].w = 0;
|
||||
convert_item_std140<Transform2D>(v, &bv->x);
|
||||
|
||||
} break;
|
||||
case RS::GLOBAL_VAR_TYPE_TRANSFORM: {
|
||||
GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index];
|
||||
Transform3D v = p_value;
|
||||
bv[0].x = v.basis.rows[0][0];
|
||||
bv[0].y = v.basis.rows[1][0];
|
||||
bv[0].z = v.basis.rows[2][0];
|
||||
bv[0].w = 0;
|
||||
|
||||
bv[1].x = v.basis.rows[0][1];
|
||||
bv[1].y = v.basis.rows[1][1];
|
||||
bv[1].z = v.basis.rows[2][1];
|
||||
bv[1].w = 0;
|
||||
|
||||
bv[2].x = v.basis.rows[0][2];
|
||||
bv[2].y = v.basis.rows[1][2];
|
||||
bv[2].z = v.basis.rows[2][2];
|
||||
bv[2].w = 0;
|
||||
|
||||
bv[3].x = v.origin.x;
|
||||
bv[3].y = v.origin.y;
|
||||
bv[3].z = v.origin.z;
|
||||
bv[3].w = 1;
|
||||
convert_item_std140<Transform3D>(v, &bv->x);
|
||||
|
||||
} break;
|
||||
default: {
|
||||
|
|
|
@ -3790,7 +3790,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
|
|||
}
|
||||
value = Variant(array);
|
||||
} else {
|
||||
value = Variant(Vector2(p_value[0].sint, p_value[1].sint));
|
||||
value = Variant(Vector2i(p_value[0].sint, p_value[1].sint));
|
||||
}
|
||||
break;
|
||||
case ShaderLanguage::TYPE_IVEC3:
|
||||
|
@ -3803,7 +3803,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
|
|||
}
|
||||
value = Variant(array);
|
||||
} else {
|
||||
value = Variant(Vector3(p_value[0].sint, p_value[1].sint, p_value[2].sint));
|
||||
value = Variant(Vector3i(p_value[0].sint, p_value[1].sint, p_value[2].sint));
|
||||
}
|
||||
break;
|
||||
case ShaderLanguage::TYPE_IVEC4:
|
||||
|
@ -3816,7 +3816,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
|
|||
}
|
||||
value = Variant(array);
|
||||
} else {
|
||||
value = Variant(Quaternion(p_value[0].sint, p_value[1].sint, p_value[2].sint, p_value[3].sint));
|
||||
value = Variant(Vector4i(p_value[0].sint, p_value[1].sint, p_value[2].sint, p_value[3].sint));
|
||||
}
|
||||
break;
|
||||
case ShaderLanguage::TYPE_UINT:
|
||||
|
@ -3840,7 +3840,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
|
|||
}
|
||||
value = Variant(array);
|
||||
} else {
|
||||
value = Variant(Vector2(p_value[0].uint, p_value[1].uint));
|
||||
value = Variant(Vector2i(p_value[0].uint, p_value[1].uint));
|
||||
}
|
||||
break;
|
||||
case ShaderLanguage::TYPE_UVEC3:
|
||||
|
@ -3853,7 +3853,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
|
|||
}
|
||||
value = Variant(array);
|
||||
} else {
|
||||
value = Variant(Vector3(p_value[0].uint, p_value[1].uint, p_value[2].uint));
|
||||
value = Variant(Vector3i(p_value[0].uint, p_value[1].uint, p_value[2].uint));
|
||||
}
|
||||
break;
|
||||
case ShaderLanguage::TYPE_UVEC4:
|
||||
|
@ -3866,7 +3866,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
|
|||
}
|
||||
value = Variant(array);
|
||||
} else {
|
||||
value = Variant(Quaternion(p_value[0].uint, p_value[1].uint, p_value[2].uint, p_value[3].uint));
|
||||
value = Variant(Vector4i(p_value[0].uint, p_value[1].uint, p_value[2].uint, p_value[3].uint));
|
||||
}
|
||||
break;
|
||||
case ShaderLanguage::TYPE_FLOAT:
|
||||
|
@ -3942,7 +3942,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
|
|||
if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
|
||||
value = Variant(Color(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real));
|
||||
} else {
|
||||
value = Variant(Quaternion(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real));
|
||||
value = Variant(Vector4(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
322
servers/rendering/storage/variant_converters.h
Normal file
322
servers/rendering/storage/variant_converters.h
Normal file
|
@ -0,0 +1,322 @@
|
|||
/**************************************************************************/
|
||||
/* variant_converters.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef VARIANT_CONVERTERS_H
|
||||
#define VARIANT_CONVERTERS_H
|
||||
|
||||
#include "core/error/error_macros.h"
|
||||
#include "core/variant/array.h"
|
||||
#include "core/variant/variant.h"
|
||||
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
|
||||
template <typename T>
|
||||
struct VariantConverterStd140 {
|
||||
// Generic base template for all Vector2/3/4(i) classes.
|
||||
static constexpr int Elements = T::AXIS_COUNT;
|
||||
|
||||
template <typename P>
|
||||
static void convert(const T &p_v, P *p_write, bool p_compact) {
|
||||
for (int i = 0; i < Elements; i++) {
|
||||
p_write[i] = p_v[i];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct VariantConverterStd140<float> {
|
||||
static constexpr int Elements = 1;
|
||||
|
||||
template <typename P>
|
||||
static void convert(float p_v, P *p_write, bool p_compact) {
|
||||
p_write[0] = p_v;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct VariantConverterStd140<int32_t> {
|
||||
static constexpr int Elements = 1;
|
||||
|
||||
template <typename P>
|
||||
static void convert(int32_t p_v, P *p_write, bool p_compact) {
|
||||
p_write[0] = p_v;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct VariantConverterStd140<uint32_t> {
|
||||
static constexpr int Elements = 1;
|
||||
|
||||
template <typename P>
|
||||
static void convert(uint32_t p_v, P *p_write, bool p_compact) {
|
||||
p_write[0] = p_v;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct VariantConverterStd140<Basis> {
|
||||
static constexpr int Elements = 9;
|
||||
|
||||
template <typename P>
|
||||
static void convert(const Basis &p_v, P *p_write, bool p_compact) {
|
||||
// Basis can have compact 9 floats or std140 layout 12 floats.
|
||||
int i = 0;
|
||||
|
||||
p_write[i++] = p_v.rows[0][0];
|
||||
p_write[i++] = p_v.rows[1][0];
|
||||
p_write[i++] = p_v.rows[2][0];
|
||||
if (!p_compact) {
|
||||
p_write[i++] = 0;
|
||||
}
|
||||
|
||||
p_write[i++] = p_v.rows[0][1];
|
||||
p_write[i++] = p_v.rows[1][1];
|
||||
p_write[i++] = p_v.rows[2][1];
|
||||
if (!p_compact) {
|
||||
p_write[i++] = 0;
|
||||
}
|
||||
|
||||
p_write[i++] = p_v.rows[0][2];
|
||||
p_write[i++] = p_v.rows[1][2];
|
||||
p_write[i++] = p_v.rows[2][2];
|
||||
if (!p_compact) {
|
||||
p_write[i++] = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct VariantConverterStd140<Transform2D> {
|
||||
static constexpr int Elements = 12;
|
||||
|
||||
template <typename P>
|
||||
static void convert(const Transform2D &p_v, P *p_write, bool p_compact) {
|
||||
p_write[0] = p_v.columns[0][0];
|
||||
p_write[1] = p_v.columns[0][1];
|
||||
p_write[2] = 0;
|
||||
p_write[3] = 0;
|
||||
|
||||
p_write[4] = p_v.columns[1][0];
|
||||
p_write[5] = p_v.columns[1][1];
|
||||
p_write[6] = 0;
|
||||
p_write[7] = 0;
|
||||
|
||||
p_write[8] = p_v.columns[2][0];
|
||||
p_write[9] = p_v.columns[2][1];
|
||||
p_write[10] = 1;
|
||||
p_write[11] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct VariantConverterStd140<Transform3D> {
|
||||
static constexpr int Elements = 16;
|
||||
|
||||
template <typename P>
|
||||
static void convert(const Transform3D &p_v, P *p_write, bool p_compact) {
|
||||
p_write[0] = p_v.basis.rows[0][0];
|
||||
p_write[1] = p_v.basis.rows[1][0];
|
||||
p_write[2] = p_v.basis.rows[2][0];
|
||||
p_write[3] = 0;
|
||||
|
||||
p_write[4] = p_v.basis.rows[0][1];
|
||||
p_write[5] = p_v.basis.rows[1][1];
|
||||
p_write[6] = p_v.basis.rows[2][1];
|
||||
p_write[7] = 0;
|
||||
|
||||
p_write[8] = p_v.basis.rows[0][2];
|
||||
p_write[9] = p_v.basis.rows[1][2];
|
||||
p_write[10] = p_v.basis.rows[2][2];
|
||||
p_write[11] = 0;
|
||||
|
||||
p_write[12] = p_v.origin.x;
|
||||
p_write[13] = p_v.origin.y;
|
||||
p_write[14] = p_v.origin.z;
|
||||
p_write[15] = 1;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct VariantConverterStd140<Projection> {
|
||||
static constexpr int Elements = 16;
|
||||
|
||||
template <typename P>
|
||||
static void convert(const Projection &p_v, P *p_write, bool p_compact) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
p_write[i * 4 + j] = p_v.columns[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename P>
|
||||
T construct_vector(const std::initializer_list<P> &values) {
|
||||
T vector{};
|
||||
int index = 0;
|
||||
for (P v : values) {
|
||||
vector[index++] = v;
|
||||
if (index >= T::AXIS_COUNT) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return vector;
|
||||
}
|
||||
|
||||
// Compatibility converter, tries to convert certain Variant types into a Vector2/3/4(i).
|
||||
|
||||
template <typename T>
|
||||
T convert_to_vector(const Variant &p_variant, bool p_linear_color = false) {
|
||||
const Variant::Type type = p_variant.get_type();
|
||||
|
||||
if (type == Variant::QUATERNION) {
|
||||
Quaternion quat = p_variant;
|
||||
return construct_vector<T>({ quat.x, quat.y, quat.z, quat.w });
|
||||
} else if (type == Variant::PLANE) {
|
||||
Plane p = p_variant;
|
||||
return construct_vector<T>({ p.normal.x, p.normal.y, p.normal.z, p.d });
|
||||
} else if (type == Variant::RECT2 || type == Variant::RECT2I) {
|
||||
Rect2 r = p_variant;
|
||||
return construct_vector<T>({ r.position.x, r.position.y, r.size.x, r.size.y });
|
||||
} else if (type == Variant::COLOR) {
|
||||
Color c = p_variant;
|
||||
if (p_linear_color) {
|
||||
c = c.srgb_to_linear();
|
||||
}
|
||||
return construct_vector<T>({ c.r, c.g, c.b, c.a });
|
||||
} else if (p_variant.is_array()) {
|
||||
const Array &array = p_variant;
|
||||
const int size = MIN(array.size(), T::AXIS_COUNT);
|
||||
T vector{};
|
||||
for (int i = 0; i < size; i++) {
|
||||
vector[i] = array.get(i);
|
||||
}
|
||||
return vector;
|
||||
}
|
||||
|
||||
return p_variant; // Default Variant conversion, covers all Vector2/3/4(i) types.
|
||||
}
|
||||
|
||||
inline bool is_number_array(const Array &p_array) {
|
||||
const int size = p_array.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (!p_array.get(i).is_num()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool is_convertible_array(Variant::Type type) {
|
||||
return type == Variant::ARRAY ||
|
||||
type == Variant::PACKED_VECTOR2_ARRAY ||
|
||||
type == Variant::PACKED_VECTOR3_ARRAY ||
|
||||
type == Variant::PACKED_COLOR_ARRAY;
|
||||
}
|
||||
|
||||
template <class, class = void>
|
||||
struct is_vector_type : std::false_type {};
|
||||
|
||||
template <class T>
|
||||
struct is_vector_type<T, std::void_t<decltype(T::AXIS_COUNT)>> : std::true_type {};
|
||||
|
||||
template <typename T, typename P>
|
||||
void convert_item_std140(const T &p_item, P *p_write, bool p_compact = false) {
|
||||
VariantConverterStd140<T>::template convert<P>(p_item, p_write, p_compact);
|
||||
}
|
||||
|
||||
template <typename T, typename P>
|
||||
Vector<P> convert_array_std140(const Variant &p_variant, [[maybe_unused]] bool p_linear_color = false) {
|
||||
if (is_convertible_array(p_variant.get_type())) {
|
||||
// Slow path, convert Variant arrays and some packed arrays manually into primitive types.
|
||||
const Array &array = p_variant;
|
||||
if (is_number_array(array)) {
|
||||
// Already flattened and converted (or empty) array, usually coming from saved resources.
|
||||
return p_variant;
|
||||
}
|
||||
|
||||
const int items = array.size();
|
||||
constexpr int elements = VariantConverterStd140<T>::Elements;
|
||||
|
||||
Vector<P> result;
|
||||
result.resize(items * elements);
|
||||
P *write = result.ptrw();
|
||||
|
||||
for (int i = 0; i < items; i++) {
|
||||
const Variant &item = array.get(i);
|
||||
P *offset = write + (i * elements);
|
||||
|
||||
if constexpr (is_vector_type<T>::value) {
|
||||
const T &vec = convert_to_vector<T>(item, p_linear_color);
|
||||
convert_item_std140<T, P>(vec, offset, true);
|
||||
} else {
|
||||
convert_item_std140<T, P>(item.operator T(), offset, true);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
} else if (p_variant.is_array()) {
|
||||
// Fast path, return the packed array directly.
|
||||
return p_variant;
|
||||
}
|
||||
|
||||
// Not an array type. Usually happens with uninitialized null shader resource parameters.
|
||||
// Just return an empty array, uniforms will be default initialized later.
|
||||
|
||||
return Vector<P>();
|
||||
}
|
||||
|
||||
template <typename T, typename From, typename To>
|
||||
void write_array_std140(const Vector<From> &p_values, To *p_write, int p_array_size, int p_stride) {
|
||||
constexpr int elements = VariantConverterStd140<T>::Elements;
|
||||
const int src_count = p_values.size();
|
||||
const int dst_count = elements * p_array_size;
|
||||
const int stride_count = p_stride * p_array_size;
|
||||
const From *read = p_values.ptr();
|
||||
const T default_value{};
|
||||
|
||||
memset(p_write, 0, sizeof(To) * stride_count);
|
||||
|
||||
for (int i = 0, j = 0; i < dst_count; i += elements, j += p_stride) {
|
||||
if (i + elements - 1 < src_count) {
|
||||
// Only copy full items with all elements, no partial or missing data.
|
||||
for (int e = 0; e < elements; e++) {
|
||||
DEV_ASSERT(j + e < stride_count && i + e < src_count);
|
||||
p_write[j + e] = read[i + e];
|
||||
}
|
||||
} else {
|
||||
// If not enough source data was passed in, write default values.
|
||||
convert_item_std140(default_value, p_write + j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // VARIANT_CONVERTERS_H
|
Loading…
Reference in a new issue