mirror of
https://github.com/godotengine/godot.git
synced 2025-02-08 03:40:52 +00:00
Fix bugs in shader swizzling
This commit is contained in:
parent
ef51726ff3
commit
01de6513ac
@ -2933,6 +2933,13 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltI
|
|||||||
} else if (p_node->type == Node::TYPE_MEMBER) {
|
} else if (p_node->type == Node::TYPE_MEMBER) {
|
||||||
|
|
||||||
MemberNode *member = static_cast<MemberNode *>(p_node);
|
MemberNode *member = static_cast<MemberNode *>(p_node);
|
||||||
|
|
||||||
|
if (member->has_swizzling_duplicates) {
|
||||||
|
if (r_message)
|
||||||
|
*r_message = RTR("Swizzling assignment contains duplicates.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return _validate_assign(member->owner, p_builtin_types, r_message);
|
return _validate_assign(member->owner, p_builtin_types, r_message);
|
||||||
|
|
||||||
} else if (p_node->type == Node::TYPE_VARIABLE) {
|
} else if (p_node->type == Node::TYPE_VARIABLE) {
|
||||||
@ -3710,9 +3717,17 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
|
|||||||
String ident = identifier;
|
String ident = identifier;
|
||||||
|
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
|
bool repeated = false;
|
||||||
DataType member_type = TYPE_VOID;
|
DataType member_type = TYPE_VOID;
|
||||||
StringName member_struct_name = "";
|
StringName member_struct_name = "";
|
||||||
int array_size = 0;
|
int array_size = 0;
|
||||||
|
|
||||||
|
Set<char> position_symbols;
|
||||||
|
Set<char> color_symbols;
|
||||||
|
Set<char> texture_symbols;
|
||||||
|
|
||||||
|
bool mix_error = false;
|
||||||
|
|
||||||
switch (dt) {
|
switch (dt) {
|
||||||
case TYPE_STRUCT: {
|
case TYPE_STRUCT: {
|
||||||
ok = false;
|
ok = false;
|
||||||
@ -3758,8 +3773,39 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
|
|||||||
switch (c[i]) {
|
switch (c[i]) {
|
||||||
case 'r':
|
case 'r':
|
||||||
case 'g':
|
case 'g':
|
||||||
|
if (position_symbols.size() > 0 || texture_symbols.size() > 0) {
|
||||||
|
mix_error = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!color_symbols.has(c[i])) {
|
||||||
|
color_symbols.insert(c[i]);
|
||||||
|
} else {
|
||||||
|
repeated = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
case 'y':
|
case 'y':
|
||||||
|
if (color_symbols.size() > 0 || texture_symbols.size() > 0) {
|
||||||
|
mix_error = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!position_symbols.has(c[i])) {
|
||||||
|
position_symbols.insert(c[i]);
|
||||||
|
} else {
|
||||||
|
repeated = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
case 't':
|
||||||
|
if (color_symbols.size() > 0 || position_symbols.size() > 0) {
|
||||||
|
mix_error = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!texture_symbols.has(c[i])) {
|
||||||
|
texture_symbols.insert(c[i]);
|
||||||
|
} else {
|
||||||
|
repeated = true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ok = false;
|
ok = false;
|
||||||
@ -3794,9 +3840,41 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
|
|||||||
case 'r':
|
case 'r':
|
||||||
case 'g':
|
case 'g':
|
||||||
case 'b':
|
case 'b':
|
||||||
|
if (position_symbols.size() > 0 || texture_symbols.size() > 0) {
|
||||||
|
mix_error = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!color_symbols.has(c[i])) {
|
||||||
|
color_symbols.insert(c[i]);
|
||||||
|
} else {
|
||||||
|
repeated = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
case 'y':
|
case 'y':
|
||||||
case 'z':
|
case 'z':
|
||||||
|
if (color_symbols.size() > 0 || texture_symbols.size() > 0) {
|
||||||
|
mix_error = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!position_symbols.has(c[i])) {
|
||||||
|
position_symbols.insert(c[i]);
|
||||||
|
} else {
|
||||||
|
repeated = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
case 't':
|
||||||
|
case 'p':
|
||||||
|
if (color_symbols.size() > 0 || position_symbols.size() > 0) {
|
||||||
|
mix_error = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!texture_symbols.has(c[i])) {
|
||||||
|
texture_symbols.insert(c[i]);
|
||||||
|
} else {
|
||||||
|
repeated = true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ok = false;
|
ok = false;
|
||||||
@ -3832,10 +3910,43 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
|
|||||||
case 'g':
|
case 'g':
|
||||||
case 'b':
|
case 'b':
|
||||||
case 'a':
|
case 'a':
|
||||||
|
if (position_symbols.size() > 0 || texture_symbols.size() > 0) {
|
||||||
|
mix_error = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!color_symbols.has(c[i])) {
|
||||||
|
color_symbols.insert(c[i]);
|
||||||
|
} else {
|
||||||
|
repeated = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
case 'y':
|
case 'y':
|
||||||
case 'z':
|
case 'z':
|
||||||
case 'w':
|
case 'w':
|
||||||
|
if (color_symbols.size() > 0 || texture_symbols.size() > 0) {
|
||||||
|
mix_error = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!position_symbols.has(c[i])) {
|
||||||
|
position_symbols.insert(c[i]);
|
||||||
|
} else {
|
||||||
|
repeated = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
case 't':
|
||||||
|
case 'p':
|
||||||
|
case 'q':
|
||||||
|
if (color_symbols.size() > 0 || position_symbols.size() > 0) {
|
||||||
|
mix_error = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!texture_symbols.has(c[i])) {
|
||||||
|
texture_symbols.insert(c[i]);
|
||||||
|
} else {
|
||||||
|
repeated = true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ok = false;
|
ok = false;
|
||||||
@ -3850,8 +3961,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ok) {
|
if (mix_error) {
|
||||||
|
_set_error("Cannot combine symbols from different sets in expression ." + ident);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
_set_error("Invalid member for " + (dt == TYPE_STRUCT ? st : get_datatype_name(dt)) + " expression: ." + ident);
|
_set_error("Invalid member for " + (dt == TYPE_STRUCT ? st : get_datatype_name(dt)) + " expression: ." + ident);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -3865,6 +3980,8 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
|
|||||||
mn->array_size = array_size;
|
mn->array_size = array_size;
|
||||||
mn->name = ident;
|
mn->name = ident;
|
||||||
mn->owner = expr;
|
mn->owner = expr;
|
||||||
|
mn->has_swizzling_duplicates = repeated;
|
||||||
|
|
||||||
if (array_size > 0) {
|
if (array_size > 0) {
|
||||||
|
|
||||||
tk = _get_token();
|
tk = _get_token();
|
||||||
@ -6684,6 +6801,7 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
|
|||||||
|
|
||||||
const char colv[4] = { 'r', 'g', 'b', 'a' };
|
const char colv[4] = { 'r', 'g', 'b', 'a' };
|
||||||
const char coordv[4] = { 'x', 'y', 'z', 'w' };
|
const char coordv[4] = { 'x', 'y', 'z', 'w' };
|
||||||
|
const char coordt[4] = { 's', 't', 'p', 'q' };
|
||||||
|
|
||||||
int limit = 0;
|
int limit = 0;
|
||||||
|
|
||||||
@ -6721,6 +6839,7 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
|
|||||||
for (int i = 0; i < limit; i++) {
|
for (int i = 0; i < limit; i++) {
|
||||||
r_options->push_back(ScriptCodeCompletionOption(String::chr(colv[i]), ScriptCodeCompletionOption::KIND_PLAIN_TEXT));
|
r_options->push_back(ScriptCodeCompletionOption(String::chr(colv[i]), ScriptCodeCompletionOption::KIND_PLAIN_TEXT));
|
||||||
r_options->push_back(ScriptCodeCompletionOption(String::chr(coordv[i]), ScriptCodeCompletionOption::KIND_PLAIN_TEXT));
|
r_options->push_back(ScriptCodeCompletionOption(String::chr(coordv[i]), ScriptCodeCompletionOption::KIND_PLAIN_TEXT));
|
||||||
|
r_options->push_back(ScriptCodeCompletionOption(String::chr(coordt[i]), ScriptCodeCompletionOption::KIND_PLAIN_TEXT));
|
||||||
}
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
@ -538,6 +538,7 @@ public:
|
|||||||
StringName name;
|
StringName name;
|
||||||
Node *owner;
|
Node *owner;
|
||||||
Node *index_expression;
|
Node *index_expression;
|
||||||
|
bool has_swizzling_duplicates;
|
||||||
|
|
||||||
virtual DataType get_datatype() const { return datatype; }
|
virtual DataType get_datatype() const { return datatype; }
|
||||||
virtual String get_datatype_name() const { return String(struct_name); }
|
virtual String get_datatype_name() const { return String(struct_name); }
|
||||||
@ -549,7 +550,8 @@ public:
|
|||||||
datatype(TYPE_VOID),
|
datatype(TYPE_VOID),
|
||||||
array_size(0),
|
array_size(0),
|
||||||
owner(NULL),
|
owner(NULL),
|
||||||
index_expression(NULL) {}
|
index_expression(NULL),
|
||||||
|
has_swizzling_duplicates(false) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StructNode : public Node {
|
struct StructNode : public Node {
|
||||||
|
Loading…
Reference in New Issue
Block a user