summaryrefslogtreecommitdiff
path: root/servers/visual/shader_language.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'servers/visual/shader_language.cpp')
-rw-r--r--servers/visual/shader_language.cpp94
1 files changed, 76 insertions, 18 deletions
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index 2069e64c43..1783ef4525 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -612,6 +612,8 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
}
ERR_PRINT("BUG");
return Token();
+
+#undef GETCHAR
}
String ShaderLanguage::token_debug(const String &p_code) {
@@ -1376,6 +1378,15 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "bvec4", TYPE_BVEC4, { TYPE_UVEC4, TYPE_VOID } },
{ "bvec4", TYPE_BVEC4, { TYPE_VEC4, TYPE_VOID } },
+ //conversion between matrixes
+
+ { "mat2", TYPE_MAT2, { TYPE_MAT3, TYPE_VOID } },
+ { "mat2", TYPE_MAT2, { TYPE_MAT4, TYPE_VOID } },
+ { "mat3", TYPE_MAT3, { TYPE_MAT2, TYPE_VOID } },
+ { "mat3", TYPE_MAT3, { TYPE_MAT4, TYPE_VOID } },
+ { "mat4", TYPE_MAT4, { TYPE_MAT2, TYPE_VOID } },
+ { "mat4", TYPE_MAT4, { TYPE_MAT3, TYPE_VOID } },
+
//builtins - trigonometry
{ "radians", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
@@ -2460,7 +2471,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
//add to current function as dependency
for (int j = 0; j < shader->functions.size(); j++) {
if (shader->functions[j].name == current_function) {
- shader->functions[j].uses_function.insert(name);
+ shader->functions.write[j].uses_function.insert(name);
break;
}
}
@@ -2545,7 +2556,9 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
TkPos pos = _get_tkpos();
tk = _get_token();
- if (tk.type == TK_PERIOD) {
+ if (tk.type == TK_CURSOR) {
+ //do nothing
+ } else if (tk.type == TK_PERIOD) {
StringName identifier;
if (_get_completable_identifier(p_block, COMPLETION_INDEX, identifier)) {
@@ -3008,8 +3021,8 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
op->arguments.push_back(expression[i + 1].node);
- expression[i].is_op = false;
- expression[i].node = op;
+ expression.write[i].is_op = false;
+ expression.write[i].node = op;
if (!_validate_operator(op, &op->return_cache)) {
@@ -3043,8 +3056,8 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
op->arguments.push_back(expression[next_op + 1].node);
op->arguments.push_back(expression[next_op + 3].node);
- expression[next_op - 1].is_op = false;
- expression[next_op - 1].node = op;
+ expression.write[next_op - 1].is_op = false;
+ expression.write[next_op - 1].node = op;
if (!_validate_operator(op, &op->return_cache)) {
String at;
@@ -3094,7 +3107,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
op->arguments.push_back(expression[next_op - 1].node); //expression goes as left
op->arguments.push_back(expression[next_op + 1].node); //next expression goes as right
- expression[next_op - 1].node = op;
+ expression.write[next_op - 1].node = op;
//replace all 3 nodes by this operator and make it an expression
@@ -3136,7 +3149,7 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha
for (int i = 1; i < op->arguments.size(); i++) {
- op->arguments[i] = _reduce_expression(p_block, op->arguments[i]);
+ op->arguments.write[i] = _reduce_expression(p_block, op->arguments[i]);
if (op->arguments[i]->type == Node::TYPE_CONSTANT) {
ConstantNode *cn = static_cast<ConstantNode *>(op->arguments[i]);
@@ -3176,7 +3189,7 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha
return cn;
} else if (op->op == OP_NEGATE) {
- op->arguments[0] = _reduce_expression(p_block, op->arguments[0]);
+ op->arguments.write[0] = _reduce_expression(p_block, op->arguments[0]);
if (op->arguments[0]->type == Node::TYPE_CONSTANT) {
ConstantNode *cn = static_cast<ConstantNode *>(op->arguments[0]);
@@ -3583,7 +3596,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
return OK;
}
-Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types) {
+Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types) {
Token tk = _get_token();
@@ -3642,7 +3655,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
return ERR_PARSE_ERROR;
}
- if (!p_render_modes.has(mode)) {
+ if (p_render_modes.find(mode) == -1) {
_set_error("Invalid render mode: '" + String(mode) + "'");
return ERR_PARSE_ERROR;
}
@@ -4062,13 +4075,58 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
return OK;
}
+// skips over whitespace and /* */ and // comments
+static int _get_first_ident_pos(const String &p_code) {
+
+ int idx = 0;
+
+#define GETCHAR(m_idx) (((idx + m_idx) < p_code.length()) ? p_code[idx + m_idx] : CharType(0))
+
+ while (true) {
+ if (GETCHAR(0) == '/' && GETCHAR(1) == '/') {
+ idx += 2;
+ while (true) {
+ if (GETCHAR(0) == 0) return 0;
+ if (GETCHAR(0) == '\n') {
+ idx++;
+ break; // loop
+ }
+ idx++;
+ }
+ } else if (GETCHAR(0) == '/' && GETCHAR(1) == '*') {
+ idx += 2;
+ while (true) {
+ if (GETCHAR(0) == 0) return 0;
+ if (GETCHAR(0) == '*' && GETCHAR(1) == '/') {
+ idx += 2;
+ break; // loop
+ }
+ idx++;
+ }
+ } else {
+ switch (GETCHAR(0)) {
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n': {
+ idx++;
+ } break; // switch
+ default:
+ return idx;
+ }
+ }
+ }
+
+#undef GETCHAR
+}
+
String ShaderLanguage::get_shader_type(const String &p_code) {
bool reading_type = false;
String cur_identifier;
- for (int i = 0; i < p_code.length(); i++) {
+ for (int i = _get_first_ident_pos(p_code); i < p_code.length(); i++) {
if (p_code[i] == ';') {
break;
@@ -4097,7 +4155,7 @@ String ShaderLanguage::get_shader_type(const String &p_code) {
return String();
}
-Error ShaderLanguage::compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types) {
+Error ShaderLanguage::compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types) {
clear();
@@ -4114,7 +4172,7 @@ Error ShaderLanguage::compile(const String &p_code, const Map<StringName, Functi
return OK;
}
-Error ShaderLanguage::complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types, List<String> *r_options, String &r_call_hint) {
+Error ShaderLanguage::complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, List<String> *r_options, String &r_call_hint) {
clear();
@@ -4130,13 +4188,13 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
switch (completion_type) {
case COMPLETION_NONE: {
- //do none
- return ERR_PARSE_ERROR;
+ //do nothing
+ return OK;
} break;
case COMPLETION_RENDER_MODE: {
- for (const Set<String>::Element *E = p_render_modes.front(); E; E = E->next()) {
+ for (int i = 0; i < p_render_modes.size(); i++) {
- r_options->push_back(E->get());
+ r_options->push_back(p_render_modes[i]);
}
return OK;