|
@@ -1078,6 +1078,9 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea
|
|
|
if (r_data_type) {
|
|
|
*r_data_type = shader->uniforms[p_identifier].type;
|
|
|
}
|
|
|
+ if (r_array_size) {
|
|
|
+ *r_array_size = shader->uniforms[p_identifier].array_size;
|
|
|
+ }
|
|
|
if (r_type) {
|
|
|
*r_type = IDENTIFIER_UNIFORM;
|
|
|
}
|
|
@@ -2921,86 +2924,294 @@ bool ShaderLanguage::is_sampler_type(DataType p_type) {
|
|
|
p_type == TYPE_SAMPLERCUBEARRAY;
|
|
|
}
|
|
|
|
|
|
-Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::ConstantNode::Value> &p_value, DataType p_type, ShaderLanguage::ShaderNode::Uniform::Hint p_hint) {
|
|
|
+Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::ConstantNode::Value> &p_value, DataType p_type, int p_array_size, ShaderLanguage::ShaderNode::Uniform::Hint p_hint) {
|
|
|
+ int array_size = p_array_size;
|
|
|
+
|
|
|
if (p_value.size() > 0) {
|
|
|
Variant value;
|
|
|
switch (p_type) {
|
|
|
case ShaderLanguage::TYPE_BOOL:
|
|
|
- value = Variant(p_value[0].boolean);
|
|
|
+ if (array_size > 0) {
|
|
|
+ PackedInt32Array array = PackedInt32Array();
|
|
|
+ for (int i = 0; i < array_size; i++) {
|
|
|
+ array.push_back(p_value[i].boolean);
|
|
|
+ }
|
|
|
+ value = Variant(array);
|
|
|
+ } else {
|
|
|
+ value = Variant(p_value[0].boolean);
|
|
|
+ }
|
|
|
break;
|
|
|
case ShaderLanguage::TYPE_BVEC2:
|
|
|
+ array_size *= 2;
|
|
|
+
|
|
|
+ if (array_size > 0) {
|
|
|
+ PackedInt32Array array = PackedInt32Array();
|
|
|
+ for (int i = 0; i < array_size; i++) {
|
|
|
+ array.push_back(p_value[i].boolean);
|
|
|
+ }
|
|
|
+ value = Variant(array);
|
|
|
+ } else {
|
|
|
+ value = Variant(p_value[0].boolean);
|
|
|
+ }
|
|
|
+ break;
|
|
|
case ShaderLanguage::TYPE_BVEC3:
|
|
|
+ array_size *= 3;
|
|
|
+
|
|
|
+ if (array_size > 0) {
|
|
|
+ PackedInt32Array array = PackedInt32Array();
|
|
|
+ for (int i = 0; i < array_size; i++) {
|
|
|
+ array.push_back(p_value[i].boolean);
|
|
|
+ }
|
|
|
+ value = Variant(array);
|
|
|
+ } else {
|
|
|
+ value = Variant(p_value[0].boolean);
|
|
|
+ }
|
|
|
+ break;
|
|
|
case ShaderLanguage::TYPE_BVEC4:
|
|
|
+ array_size *= 4;
|
|
|
+
|
|
|
+ if (array_size > 0) {
|
|
|
+ PackedInt32Array array = PackedInt32Array();
|
|
|
+ for (int i = 0; i < array_size; i++) {
|
|
|
+ array.push_back(p_value[i].boolean);
|
|
|
+ }
|
|
|
+ value = Variant(array);
|
|
|
+ } else {
|
|
|
+ value = Variant(p_value[0].boolean);
|
|
|
+ }
|
|
|
+ break;
|
|
|
case ShaderLanguage::TYPE_INT:
|
|
|
- value = Variant(p_value[0].sint);
|
|
|
+ if (array_size > 0) {
|
|
|
+ PackedInt32Array array = PackedInt32Array();
|
|
|
+ for (int i = 0; i < array_size; i++) {
|
|
|
+ array.push_back(p_value[i].sint);
|
|
|
+ }
|
|
|
+ value = Variant(array);
|
|
|
+ } else {
|
|
|
+ value = Variant(p_value[0].sint);
|
|
|
+ }
|
|
|
break;
|
|
|
case ShaderLanguage::TYPE_IVEC2:
|
|
|
- value = Variant(Vector2(p_value[0].sint, p_value[1].sint));
|
|
|
+ if (array_size > 0) {
|
|
|
+ array_size *= 2;
|
|
|
+
|
|
|
+ PackedInt32Array array = PackedInt32Array();
|
|
|
+ for (int i = 0; i < array_size; i++) {
|
|
|
+ array.push_back(p_value[i].sint);
|
|
|
+ }
|
|
|
+ value = Variant(array);
|
|
|
+ } else {
|
|
|
+ value = Variant(Vector2(p_value[0].sint, p_value[1].sint));
|
|
|
+ }
|
|
|
break;
|
|
|
case ShaderLanguage::TYPE_IVEC3:
|
|
|
- value = Variant(Vector3(p_value[0].sint, p_value[1].sint, p_value[2].sint));
|
|
|
+ if (array_size > 0) {
|
|
|
+ array_size *= 3;
|
|
|
+
|
|
|
+ PackedInt32Array array = PackedInt32Array();
|
|
|
+ for (int i = 0; i < array_size; i++) {
|
|
|
+ array.push_back(p_value[i].sint);
|
|
|
+ }
|
|
|
+ value = Variant(array);
|
|
|
+ } else {
|
|
|
+ value = Variant(Vector3(p_value[0].sint, p_value[1].sint, p_value[2].sint));
|
|
|
+ }
|
|
|
break;
|
|
|
case ShaderLanguage::TYPE_IVEC4:
|
|
|
- value = Variant(Plane(p_value[0].sint, p_value[1].sint, p_value[2].sint, p_value[3].sint));
|
|
|
+ if (array_size > 0) {
|
|
|
+ array_size *= 4;
|
|
|
+
|
|
|
+ PackedInt32Array array = PackedInt32Array();
|
|
|
+ for (int i = 0; i < array_size; i++) {
|
|
|
+ array.push_back(p_value[i].sint);
|
|
|
+ }
|
|
|
+ value = Variant(array);
|
|
|
+ } else {
|
|
|
+ value = Variant(Plane(p_value[0].sint, p_value[1].sint, p_value[2].sint, p_value[3].sint));
|
|
|
+ }
|
|
|
break;
|
|
|
case ShaderLanguage::TYPE_UINT:
|
|
|
- value = Variant(p_value[0].uint);
|
|
|
+ if (array_size > 0) {
|
|
|
+ PackedInt32Array array = PackedInt32Array();
|
|
|
+ for (int i = 0; i < array_size; i++) {
|
|
|
+ array.push_back(p_value[i].uint);
|
|
|
+ }
|
|
|
+ value = Variant(array);
|
|
|
+ } else {
|
|
|
+ value = Variant(p_value[0].uint);
|
|
|
+ }
|
|
|
break;
|
|
|
case ShaderLanguage::TYPE_UVEC2:
|
|
|
- value = Variant(Vector2(p_value[0].uint, p_value[1].uint));
|
|
|
+ if (array_size > 0) {
|
|
|
+ array_size *= 2;
|
|
|
+
|
|
|
+ PackedInt32Array array = PackedInt32Array();
|
|
|
+ for (int i = 0; i < array_size; i++) {
|
|
|
+ array.push_back(p_value[i].uint);
|
|
|
+ }
|
|
|
+ value = Variant(array);
|
|
|
+ } else {
|
|
|
+ value = Variant(Vector2(p_value[0].uint, p_value[1].uint));
|
|
|
+ }
|
|
|
break;
|
|
|
case ShaderLanguage::TYPE_UVEC3:
|
|
|
- value = Variant(Vector3(p_value[0].uint, p_value[1].uint, p_value[2].uint));
|
|
|
+ if (array_size > 0) {
|
|
|
+ array_size *= 3;
|
|
|
+
|
|
|
+ PackedInt32Array array = PackedInt32Array();
|
|
|
+ for (int i = 0; i < array_size; i++) {
|
|
|
+ array.push_back(p_value[i].uint);
|
|
|
+ }
|
|
|
+ value = Variant(array);
|
|
|
+ } else {
|
|
|
+ value = Variant(Vector3(p_value[0].uint, p_value[1].uint, p_value[2].uint));
|
|
|
+ }
|
|
|
break;
|
|
|
case ShaderLanguage::TYPE_UVEC4:
|
|
|
- value = Variant(Plane(p_value[0].uint, p_value[1].uint, p_value[2].uint, p_value[3].uint));
|
|
|
+ if (array_size > 0) {
|
|
|
+ array_size *= 4;
|
|
|
+
|
|
|
+ PackedInt32Array array = PackedInt32Array();
|
|
|
+ for (int i = 0; i < array_size; i++) {
|
|
|
+ array.push_back(p_value[i].uint);
|
|
|
+ }
|
|
|
+ value = Variant(array);
|
|
|
+ } else {
|
|
|
+ value = Variant(Plane(p_value[0].uint, p_value[1].uint, p_value[2].uint, p_value[3].uint));
|
|
|
+ }
|
|
|
break;
|
|
|
case ShaderLanguage::TYPE_FLOAT:
|
|
|
- value = Variant(p_value[0].real);
|
|
|
+ if (array_size > 0) {
|
|
|
+ PackedFloat32Array array = PackedFloat32Array();
|
|
|
+ for (int i = 0; i < array_size; i++) {
|
|
|
+ array.push_back(p_value[i].real);
|
|
|
+ }
|
|
|
+ value = Variant(array);
|
|
|
+ } else {
|
|
|
+ value = Variant(p_value[0].real);
|
|
|
+ }
|
|
|
break;
|
|
|
case ShaderLanguage::TYPE_VEC2:
|
|
|
- value = Variant(Vector2(p_value[0].real, p_value[1].real));
|
|
|
+ if (array_size > 0) {
|
|
|
+ array_size *= 2;
|
|
|
+
|
|
|
+ PackedVector2Array array = PackedVector2Array();
|
|
|
+ for (int i = 0; i < array_size; i += 2) {
|
|
|
+ array.push_back(Vector2(p_value[i].real, p_value[i + 1].real));
|
|
|
+ }
|
|
|
+ value = Variant(array);
|
|
|
+ } else {
|
|
|
+ value = Variant(Vector2(p_value[0].real, p_value[1].real));
|
|
|
+ }
|
|
|
break;
|
|
|
case ShaderLanguage::TYPE_VEC3:
|
|
|
- value = Variant(Vector3(p_value[0].real, p_value[1].real, p_value[2].real));
|
|
|
+ if (array_size > 0) {
|
|
|
+ array_size *= 3;
|
|
|
+
|
|
|
+ PackedVector3Array array = PackedVector3Array();
|
|
|
+ for (int i = 0; i < array_size; i += 3) {
|
|
|
+ array.push_back(Vector3(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real));
|
|
|
+ }
|
|
|
+ value = Variant(array);
|
|
|
+ } else {
|
|
|
+ value = Variant(Vector3(p_value[0].real, p_value[1].real, p_value[2].real));
|
|
|
+ }
|
|
|
break;
|
|
|
case ShaderLanguage::TYPE_VEC4:
|
|
|
- if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
|
|
|
- value = Variant(Color(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real));
|
|
|
+ if (array_size > 0) {
|
|
|
+ array_size *= 4;
|
|
|
+
|
|
|
+ if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
|
|
|
+ PackedColorArray array = PackedColorArray();
|
|
|
+ for (int i = 0; i < array_size; i += 4) {
|
|
|
+ array.push_back(Color(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real, p_value[i + 3].real));
|
|
|
+ }
|
|
|
+ value = Variant(array);
|
|
|
+ } else {
|
|
|
+ PackedFloat32Array array = PackedFloat32Array();
|
|
|
+ for (int i = 0; i < array_size; i += 4) {
|
|
|
+ array.push_back(p_value[i].real);
|
|
|
+ array.push_back(p_value[i + 1].real);
|
|
|
+ array.push_back(p_value[i + 2].real);
|
|
|
+ array.push_back(p_value[i + 3].real);
|
|
|
+ }
|
|
|
+ value = Variant(array);
|
|
|
+ }
|
|
|
} else {
|
|
|
- value = Variant(Plane(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real));
|
|
|
+ if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
|
|
|
+ value = Variant(Color(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real));
|
|
|
+ } else {
|
|
|
+ value = Variant(Plane(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real));
|
|
|
+ }
|
|
|
}
|
|
|
break;
|
|
|
case ShaderLanguage::TYPE_MAT2:
|
|
|
- value = Variant(Transform2D(p_value[0].real, p_value[2].real, p_value[1].real, p_value[3].real, 0.0, 0.0));
|
|
|
+ if (array_size > 0) {
|
|
|
+ array_size *= 4;
|
|
|
+
|
|
|
+ PackedFloat32Array array = PackedFloat32Array();
|
|
|
+ for (int i = 0; i < array_size; i += 4) {
|
|
|
+ array.push_back(p_value[i].real);
|
|
|
+ array.push_back(p_value[i + 1].real);
|
|
|
+ array.push_back(p_value[i + 2].real);
|
|
|
+ array.push_back(p_value[i + 3].real);
|
|
|
+ }
|
|
|
+ value = Variant(array);
|
|
|
+ } else {
|
|
|
+ value = Variant(Transform2D(p_value[0].real, p_value[2].real, p_value[1].real, p_value[3].real, 0.0, 0.0));
|
|
|
+ }
|
|
|
break;
|
|
|
case ShaderLanguage::TYPE_MAT3: {
|
|
|
- Basis p;
|
|
|
- p[0][0] = p_value[0].real;
|
|
|
- p[0][1] = p_value[1].real;
|
|
|
- p[0][2] = p_value[2].real;
|
|
|
- p[1][0] = p_value[3].real;
|
|
|
- p[1][1] = p_value[4].real;
|
|
|
- p[1][2] = p_value[5].real;
|
|
|
- p[2][0] = p_value[6].real;
|
|
|
- p[2][1] = p_value[7].real;
|
|
|
- p[2][2] = p_value[8].real;
|
|
|
- value = Variant(p);
|
|
|
+ if (array_size > 0) {
|
|
|
+ array_size *= 9;
|
|
|
+
|
|
|
+ PackedFloat32Array array = PackedFloat32Array();
|
|
|
+ for (int i = 0; i < array_size; i += 9) {
|
|
|
+ for (int j = 0; j < 9; j++) {
|
|
|
+ array.push_back(p_value[i + j].real);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ value = Variant(array);
|
|
|
+ } else {
|
|
|
+ Basis p;
|
|
|
+ p[0][0] = p_value[0].real;
|
|
|
+ p[0][1] = p_value[1].real;
|
|
|
+ p[0][2] = p_value[2].real;
|
|
|
+ p[1][0] = p_value[3].real;
|
|
|
+ p[1][1] = p_value[4].real;
|
|
|
+ p[1][2] = p_value[5].real;
|
|
|
+ p[2][0] = p_value[6].real;
|
|
|
+ p[2][1] = p_value[7].real;
|
|
|
+ p[2][2] = p_value[8].real;
|
|
|
+ value = Variant(p);
|
|
|
+ }
|
|
|
break;
|
|
|
}
|
|
|
case ShaderLanguage::TYPE_MAT4: {
|
|
|
- Basis p;
|
|
|
- p[0][0] = p_value[0].real;
|
|
|
- p[0][1] = p_value[1].real;
|
|
|
- p[0][2] = p_value[2].real;
|
|
|
- p[1][0] = p_value[4].real;
|
|
|
- p[1][1] = p_value[5].real;
|
|
|
- p[1][2] = p_value[6].real;
|
|
|
- p[2][0] = p_value[8].real;
|
|
|
- p[2][1] = p_value[9].real;
|
|
|
- p[2][2] = p_value[10].real;
|
|
|
- Transform3D t = Transform3D(p, Vector3(p_value[3].real, p_value[7].real, p_value[11].real));
|
|
|
- value = Variant(t);
|
|
|
+ if (array_size > 0) {
|
|
|
+ array_size *= 16;
|
|
|
+
|
|
|
+ PackedFloat32Array array = PackedFloat32Array();
|
|
|
+ for (int i = 0; i < array_size; i += 16) {
|
|
|
+ for (int j = 0; j < 16; j++) {
|
|
|
+ array.push_back(p_value[i + j].real);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ value = Variant(array);
|
|
|
+ } else {
|
|
|
+ Basis p;
|
|
|
+ p[0][0] = p_value[0].real;
|
|
|
+ p[0][1] = p_value[1].real;
|
|
|
+ p[0][2] = p_value[2].real;
|
|
|
+ p[1][0] = p_value[4].real;
|
|
|
+ p[1][1] = p_value[5].real;
|
|
|
+ p[1][2] = p_value[6].real;
|
|
|
+ p[2][0] = p_value[8].real;
|
|
|
+ p[2][1] = p_value[9].real;
|
|
|
+ p[2][2] = p_value[10].real;
|
|
|
+ Transform3D t = Transform3D(p, Vector3(p_value[3].real, p_value[7].real, p_value[11].real));
|
|
|
+ value = Variant(t);
|
|
|
+ }
|
|
|
break;
|
|
|
}
|
|
|
case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
|
|
@@ -3036,31 +3247,50 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform
|
|
|
pi.type = Variant::NIL;
|
|
|
break;
|
|
|
case ShaderLanguage::TYPE_BOOL:
|
|
|
- pi.type = Variant::BOOL;
|
|
|
+ if (p_uniform.array_size > 0) {
|
|
|
+ pi.type = Variant::PACKED_INT32_ARRAY;
|
|
|
+ } else {
|
|
|
+ pi.type = Variant::BOOL;
|
|
|
+ }
|
|
|
break;
|
|
|
case ShaderLanguage::TYPE_BVEC2:
|
|
|
- pi.type = Variant::INT;
|
|
|
- pi.hint = PROPERTY_HINT_FLAGS;
|
|
|
- pi.hint_string = "x,y";
|
|
|
+ if (p_uniform.array_size > 0) {
|
|
|
+ pi.type = Variant::PACKED_INT32_ARRAY;
|
|
|
+ } else {
|
|
|
+ pi.type = Variant::INT;
|
|
|
+ pi.hint = PROPERTY_HINT_FLAGS;
|
|
|
+ pi.hint_string = "x,y";
|
|
|
+ }
|
|
|
break;
|
|
|
case ShaderLanguage::TYPE_BVEC3:
|
|
|
- pi.type = Variant::INT;
|
|
|
- pi.hint = PROPERTY_HINT_FLAGS;
|
|
|
- pi.hint_string = "x,y,z";
|
|
|
+ if (p_uniform.array_size > 0) {
|
|
|
+ pi.type = Variant::PACKED_INT32_ARRAY;
|
|
|
+ } else {
|
|
|
+ pi.type = Variant::INT;
|
|
|
+ pi.hint = PROPERTY_HINT_FLAGS;
|
|
|
+ pi.hint_string = "x,y,z";
|
|
|
+ }
|
|
|
break;
|
|
|
case ShaderLanguage::TYPE_BVEC4:
|
|
|
- pi.type = Variant::INT;
|
|
|
- pi.hint = PROPERTY_HINT_FLAGS;
|
|
|
- pi.hint_string = "x,y,z,w";
|
|
|
+ if (p_uniform.array_size > 0) {
|
|
|
+ pi.type = Variant::PACKED_INT32_ARRAY;
|
|
|
+ } else {
|
|
|
+ pi.type = Variant::INT;
|
|
|
+ pi.hint = PROPERTY_HINT_FLAGS;
|
|
|
+ pi.hint_string = "x,y,z,w";
|
|
|
+ }
|
|
|
break;
|
|
|
case ShaderLanguage::TYPE_UINT:
|
|
|
case ShaderLanguage::TYPE_INT: {
|
|
|
- pi.type = Variant::INT;
|
|
|
- if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) {
|
|
|
- pi.hint = PROPERTY_HINT_RANGE;
|
|
|
- pi.hint_string = rtos(p_uniform.hint_range[0]) + "," + rtos(p_uniform.hint_range[1]) + "," + rtos(p_uniform.hint_range[2]);
|
|
|
+ if (p_uniform.array_size > 0) {
|
|
|
+ pi.type = Variant::PACKED_INT32_ARRAY;
|
|
|
+ } else {
|
|
|
+ pi.type = Variant::INT;
|
|
|
+ if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) {
|
|
|
+ pi.hint = PROPERTY_HINT_RANGE;
|
|
|
+ pi.hint_string = rtos(p_uniform.hint_range[0]) + "," + rtos(p_uniform.hint_range[1]) + "," + rtos(p_uniform.hint_range[2]);
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
} break;
|
|
|
case ShaderLanguage::TYPE_IVEC2:
|
|
|
case ShaderLanguage::TYPE_IVEC3:
|
|
@@ -3071,59 +3301,106 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform
|
|
|
pi.type = Variant::PACKED_INT32_ARRAY;
|
|
|
} break;
|
|
|
case ShaderLanguage::TYPE_FLOAT: {
|
|
|
- pi.type = Variant::FLOAT;
|
|
|
- if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) {
|
|
|
- pi.hint = PROPERTY_HINT_RANGE;
|
|
|
- pi.hint_string = rtos(p_uniform.hint_range[0]) + "," + rtos(p_uniform.hint_range[1]) + "," + rtos(p_uniform.hint_range[2]);
|
|
|
+ if (p_uniform.array_size > 0) {
|
|
|
+ pi.type = Variant::PACKED_FLOAT32_ARRAY;
|
|
|
+ } else {
|
|
|
+ pi.type = Variant::FLOAT;
|
|
|
+ if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) {
|
|
|
+ pi.hint = PROPERTY_HINT_RANGE;
|
|
|
+ pi.hint_string = rtos(p_uniform.hint_range[0]) + "," + rtos(p_uniform.hint_range[1]) + "," + rtos(p_uniform.hint_range[2]);
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
} break;
|
|
|
case ShaderLanguage::TYPE_VEC2:
|
|
|
- pi.type = Variant::VECTOR2;
|
|
|
+ if (p_uniform.array_size > 0) {
|
|
|
+ pi.type = Variant::PACKED_VECTOR2_ARRAY;
|
|
|
+ } else {
|
|
|
+ pi.type = Variant::VECTOR2;
|
|
|
+ }
|
|
|
break;
|
|
|
case ShaderLanguage::TYPE_VEC3:
|
|
|
- pi.type = Variant::VECTOR3;
|
|
|
+ if (p_uniform.array_size > 0) {
|
|
|
+ pi.type = Variant::PACKED_VECTOR3_ARRAY;
|
|
|
+ } else {
|
|
|
+ pi.type = Variant::VECTOR3;
|
|
|
+ }
|
|
|
break;
|
|
|
case ShaderLanguage::TYPE_VEC4: {
|
|
|
- if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
|
|
|
- pi.type = Variant::COLOR;
|
|
|
+ if (p_uniform.array_size > 0) {
|
|
|
+ if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
|
|
|
+ pi.type = Variant::PACKED_COLOR_ARRAY;
|
|
|
+ } else {
|
|
|
+ pi.type = Variant::PACKED_FLOAT32_ARRAY;
|
|
|
+ }
|
|
|
} else {
|
|
|
- pi.type = Variant::PLANE;
|
|
|
+ if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
|
|
|
+ pi.type = Variant::COLOR;
|
|
|
+ } else {
|
|
|
+ pi.type = Variant::PLANE;
|
|
|
+ }
|
|
|
}
|
|
|
} break;
|
|
|
case ShaderLanguage::TYPE_MAT2:
|
|
|
- pi.type = Variant::TRANSFORM2D;
|
|
|
+ if (p_uniform.array_size > 0) {
|
|
|
+ pi.type = Variant::PACKED_FLOAT32_ARRAY;
|
|
|
+ } else {
|
|
|
+ pi.type = Variant::TRANSFORM2D;
|
|
|
+ }
|
|
|
break;
|
|
|
case ShaderLanguage::TYPE_MAT3:
|
|
|
- pi.type = Variant::BASIS;
|
|
|
+ if (p_uniform.array_size > 0) {
|
|
|
+ pi.type = Variant::PACKED_FLOAT32_ARRAY;
|
|
|
+ } else {
|
|
|
+ pi.type = Variant::BASIS;
|
|
|
+ }
|
|
|
break;
|
|
|
case ShaderLanguage::TYPE_MAT4:
|
|
|
- pi.type = Variant::TRANSFORM3D;
|
|
|
+ if (p_uniform.array_size > 0) {
|
|
|
+ pi.type = Variant::PACKED_FLOAT32_ARRAY;
|
|
|
+ } else {
|
|
|
+ pi.type = Variant::TRANSFORM3D;
|
|
|
+ }
|
|
|
break;
|
|
|
case ShaderLanguage::TYPE_SAMPLER2D:
|
|
|
case ShaderLanguage::TYPE_ISAMPLER2D:
|
|
|
case ShaderLanguage::TYPE_USAMPLER2D: {
|
|
|
- pi.type = Variant::OBJECT;
|
|
|
+ if (p_uniform.array_size > 0) {
|
|
|
+ pi.type = Variant::ARRAY;
|
|
|
+ } else {
|
|
|
+ pi.type = Variant::OBJECT;
|
|
|
+ }
|
|
|
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
|
|
|
pi.hint_string = "Texture2D";
|
|
|
} break;
|
|
|
case ShaderLanguage::TYPE_SAMPLER2DARRAY:
|
|
|
case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
|
|
|
case ShaderLanguage::TYPE_USAMPLER2DARRAY: {
|
|
|
- pi.type = Variant::OBJECT;
|
|
|
+ if (p_uniform.array_size > 0) {
|
|
|
+ pi.type = Variant::ARRAY;
|
|
|
+ } else {
|
|
|
+ pi.type = Variant::OBJECT;
|
|
|
+ }
|
|
|
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
|
|
|
pi.hint_string = "TextureLayered";
|
|
|
} break;
|
|
|
case ShaderLanguage::TYPE_SAMPLER3D:
|
|
|
case ShaderLanguage::TYPE_ISAMPLER3D:
|
|
|
case ShaderLanguage::TYPE_USAMPLER3D: {
|
|
|
- pi.type = Variant::OBJECT;
|
|
|
+ if (p_uniform.array_size > 0) {
|
|
|
+ pi.type = Variant::ARRAY;
|
|
|
+ } else {
|
|
|
+ pi.type = Variant::OBJECT;
|
|
|
+ }
|
|
|
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
|
|
|
pi.hint_string = "Texture3D";
|
|
|
} break;
|
|
|
case ShaderLanguage::TYPE_SAMPLERCUBE:
|
|
|
case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: {
|
|
|
- pi.type = Variant::OBJECT;
|
|
|
+ if (p_uniform.array_size > 0) {
|
|
|
+ pi.type = Variant::ARRAY;
|
|
|
+ } else {
|
|
|
+ pi.type = Variant::OBJECT;
|
|
|
+ }
|
|
|
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
|
|
|
pi.hint_string = "TextureLayered";
|
|
|
} break;
|
|
@@ -6694,6 +6971,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
|
|
|
tk = _get_token();
|
|
|
|
|
|
int texture_uniforms = 0;
|
|
|
+ int texture_binding = 0;
|
|
|
int uniforms = 0;
|
|
|
int instance_index = 0;
|
|
|
ShaderNode::Uniform::Scope uniform_scope = ShaderNode::Uniform::SCOPE_LOCAL;
|
|
@@ -6903,6 +7181,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ bool precision_defined = false;
|
|
|
DataPrecision precision = PRECISION_DEFAULT;
|
|
|
DataInterpolation interpolation = INTERPOLATION_SMOOTH;
|
|
|
DataType type;
|
|
@@ -6911,15 +7190,34 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
|
|
|
|
|
|
tk = _get_token();
|
|
|
if (is_token_interpolation(tk.type)) {
|
|
|
+ if (uniform) {
|
|
|
+ _set_error("Interpolation qualifiers are not supported for uniforms!");
|
|
|
+ return ERR_PARSE_ERROR;
|
|
|
+ }
|
|
|
interpolation = get_token_interpolation(tk.type);
|
|
|
tk = _get_token();
|
|
|
}
|
|
|
|
|
|
if (is_token_precision(tk.type)) {
|
|
|
precision = get_token_precision(tk.type);
|
|
|
+ precision_defined = true;
|
|
|
tk = _get_token();
|
|
|
}
|
|
|
|
|
|
+ if (shader->structs.has(tk.text)) {
|
|
|
+ if (uniform) {
|
|
|
+ if (precision_defined) {
|
|
|
+ _set_error("Precision modifier cannot be used on structs.");
|
|
|
+ return ERR_PARSE_ERROR;
|
|
|
+ }
|
|
|
+ _set_error("struct datatype is not yet supported for uniforms!");
|
|
|
+ return ERR_PARSE_ERROR;
|
|
|
+ } else {
|
|
|
+ _set_error("struct datatype not allowed here");
|
|
|
+ return ERR_PARSE_ERROR;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (!is_token_datatype(tk.type)) {
|
|
|
_set_error("Expected datatype. ");
|
|
|
return ERR_PARSE_ERROR;
|
|
@@ -6996,12 +7294,47 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
|
|
|
}
|
|
|
ShaderNode::Uniform uniform2;
|
|
|
|
|
|
+ uniform2.type = type;
|
|
|
+ uniform2.scope = uniform_scope;
|
|
|
+ uniform2.precision = precision;
|
|
|
+ uniform2.array_size = array_size;
|
|
|
+
|
|
|
+ tk = _get_token();
|
|
|
+ if (tk.type == TK_BRACKET_OPEN) {
|
|
|
+ if (uniform2.array_size > 0) {
|
|
|
+ _set_error("Array size is already defined!");
|
|
|
+ return ERR_PARSE_ERROR;
|
|
|
+ }
|
|
|
+ tk = _get_token();
|
|
|
+
|
|
|
+ if (tk.type == TK_INT_CONSTANT && tk.constant > 0) {
|
|
|
+ uniform2.array_size = (int)tk.constant;
|
|
|
+
|
|
|
+ tk = _get_token();
|
|
|
+ if (tk.type == TK_BRACKET_CLOSE) {
|
|
|
+ tk = _get_token();
|
|
|
+ } else {
|
|
|
+ _set_error("Expected ']'");
|
|
|
+ return ERR_PARSE_ERROR;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ _set_error("Expected integer constant > 0");
|
|
|
+ return ERR_PARSE_ERROR;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (is_sampler_type(type)) {
|
|
|
if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE) {
|
|
|
_set_error("Uniforms with 'instance' qualifiers can't be of sampler type.");
|
|
|
return ERR_PARSE_ERROR;
|
|
|
}
|
|
|
uniform2.texture_order = texture_uniforms++;
|
|
|
+ uniform2.texture_binding = texture_binding;
|
|
|
+ if (uniform2.array_size > 0) {
|
|
|
+ texture_binding += uniform2.array_size;
|
|
|
+ } else {
|
|
|
+ ++texture_binding;
|
|
|
+ }
|
|
|
uniform2.order = -1;
|
|
|
if (_validate_datatype(type) != OK) {
|
|
|
return ERR_PARSE_ERROR;
|
|
@@ -7011,19 +7344,22 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
|
|
|
_set_error("Uniforms with 'instance' qualifiers can't be of matrix type.");
|
|
|
return ERR_PARSE_ERROR;
|
|
|
}
|
|
|
-
|
|
|
uniform2.texture_order = -1;
|
|
|
if (uniform_scope != ShaderNode::Uniform::SCOPE_INSTANCE) {
|
|
|
uniform2.order = uniforms++;
|
|
|
}
|
|
|
}
|
|
|
- uniform2.type = type;
|
|
|
- uniform2.scope = uniform_scope;
|
|
|
- uniform2.precision = precision;
|
|
|
-
|
|
|
- //todo parse default value
|
|
|
|
|
|
- tk = _get_token();
|
|
|
+ if (uniform2.array_size > 0) {
|
|
|
+ if (uniform_scope == ShaderNode::Uniform::SCOPE_GLOBAL) {
|
|
|
+ _set_error("'SCOPE_GLOBAL' qualifier is not yet supported for uniform array!");
|
|
|
+ return ERR_PARSE_ERROR;
|
|
|
+ }
|
|
|
+ if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE) {
|
|
|
+ _set_error("'SCOPE_INSTANCE' qualifier is not yet supported for uniform array!");
|
|
|
+ return ERR_PARSE_ERROR;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
int custom_instance_index = -1;
|
|
|
|
|
@@ -7031,6 +7367,14 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
|
|
|
//hint
|
|
|
do {
|
|
|
tk = _get_token();
|
|
|
+
|
|
|
+ if (uniform2.array_size > 0) {
|
|
|
+ if (tk.type != TK_HINT_COLOR) {
|
|
|
+ _set_error("This hint is not yet supported for uniform arrays!");
|
|
|
+ return ERR_PARSE_ERROR;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (tk.type == TK_HINT_WHITE_TEXTURE) {
|
|
|
uniform2.hint = ShaderNode::Uniform::HINT_WHITE;
|
|
|
} else if (tk.type == TK_HINT_BLACK_TEXTURE) {
|
|
@@ -7221,6 +7565,11 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
|
|
|
//reset scope for next uniform
|
|
|
|
|
|
if (tk.type == TK_OP_ASSIGN) {
|
|
|
+ if (uniform2.array_size > 0) {
|
|
|
+ _set_error("Setting default value to a uniform array is not yet supported!");
|
|
|
+ return ERR_PARSE_ERROR;
|
|
|
+ }
|
|
|
+
|
|
|
Node *expr = _parse_and_reduce_expression(nullptr, FunctionInfo());
|
|
|
if (!expr) {
|
|
|
return ERR_PARSE_ERROR;
|
|
@@ -7265,7 +7614,11 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
|
|
|
|
|
|
tk = _get_token();
|
|
|
if (tk.type != TK_SEMICOLON && tk.type != TK_BRACKET_OPEN) {
|
|
|
- _set_error("Expected ';' or '['");
|
|
|
+ if (array_size == 0) {
|
|
|
+ _set_error("Expected ';' or '['");
|
|
|
+ } else {
|
|
|
+ _set_error("Expected ';'");
|
|
|
+ }
|
|
|
return ERR_PARSE_ERROR;
|
|
|
}
|
|
|
|
|
@@ -7290,7 +7643,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
|
|
|
return ERR_PARSE_ERROR;
|
|
|
}
|
|
|
} else {
|
|
|
- _set_error("Expected single integer constant > 0");
|
|
|
+ _set_error("Expected integer constant > 0");
|
|
|
return ERR_PARSE_ERROR;
|
|
|
}
|
|
|
}
|