diff options
Diffstat (limited to 'servers/visual')
20 files changed, 482 insertions, 356 deletions
diff --git a/servers/visual/rasterizer.cpp b/servers/visual/rasterizer.cpp index 6c04d1de63..5e02238e85 100644 --- a/servers/visual/rasterizer.cpp +++ b/servers/visual/rasterizer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index f78b4aaf5f..39530bbbee 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -55,6 +55,7 @@ public: virtual void environment_set_background(RID p_env, VS::EnvironmentBG p_bg) = 0; virtual void environment_set_sky(RID p_env, RID p_sky) = 0; virtual void environment_set_sky_custom_fov(RID p_env, float p_scale) = 0; + virtual void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) = 0; virtual void environment_set_bg_color(RID p_env, const Color &p_color) = 0; virtual void environment_set_bg_energy(RID p_env, float p_energy) = 0; virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) = 0; @@ -140,6 +141,7 @@ public: virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) = 0; virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0) = 0; virtual void light_instance_mark_visible(RID p_light_instance) = 0; + virtual bool light_instances_can_render_shadow_cube() const { return true; } virtual RID reflection_atlas_create() = 0; virtual void reflection_atlas_set_size(RID p_ref_atlas, int p_size) = 0; @@ -219,6 +221,7 @@ public: virtual void textures_keep_original(bool p_enable) = 0; virtual void texture_set_proxy(RID p_proxy, RID p_base) = 0; + virtual Size2 texture_size_with_proxy(RID p_texture) const = 0; virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) = 0; /* SKY API */ @@ -352,6 +355,7 @@ public: virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) = 0; virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const = 0; virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) = 0; + virtual void skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform &p_world_transform) = 0; /* Light API */ @@ -550,6 +554,7 @@ public: virtual RID render_target_create() = 0; virtual void render_target_set_size(RID p_render_target, int p_width, int p_height) = 0; virtual RID render_target_get_texture(RID p_render_target) const = 0; + virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) = 0; virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) = 0; virtual bool render_target_was_used(RID p_render_target) = 0; virtual void render_target_clear_used(RID p_render_target) = 0; @@ -655,7 +660,7 @@ public: next_ptr = NULL; mask_next_ptr = NULL; filter_next_ptr = NULL; - shadow_buffer_size = 256; + shadow_buffer_size = 2048; shadow_gradient_length = 0; shadow_filter = VS::CANVAS_LIGHT_FILTER_NONE; shadow_smooth = 0.0; @@ -867,7 +872,7 @@ public: Rect2 global_rect_cache; const Rect2 &get_rect() const { - if (custom_rect || !rect_dirty) + if (custom_rect || (!rect_dirty && !update_when_visible)) return rect; //must update rect @@ -937,9 +942,8 @@ public: const Item::CommandPrimitive *primitive = static_cast<const Item::CommandPrimitive *>(c); r.position = primitive->points[0]; - for (int i = 1; i < primitive->points.size(); i++) { - - r.expand_to(primitive->points[i]); + for (int j = 1; j < primitive->points.size(); j++) { + r.expand_to(primitive->points[j]); } } break; case Item::Command::TYPE_POLYGON: { @@ -948,9 +952,8 @@ public: int l = polygon->points.size(); const Point2 *pp = &polygon->points[0]; r.position = pp[0]; - for (int i = 1; i < l; i++) { - - r.expand_to(pp[i]); + for (int j = 1; j < l; j++) { + r.expand_to(pp[j]); } } break; case Item::Command::TYPE_MESH: { @@ -1099,7 +1102,7 @@ public: virtual void initialize() = 0; virtual void begin_frame(double frame_step) = 0; virtual void set_current_render_target(RID p_render_target) = 0; - virtual void restore_render_target() = 0; + virtual void restore_render_target(bool p_3d) = 0; virtual void clear_render_target(const Color &p_color) = 0; virtual void blit_render_target_to_screen(RID p_render_target, const Rect2 &p_screen_rect, int p_screen = 0) = 0; virtual void output_lens_distorted_to_screen(RID p_render_target, const Rect2 &p_screen_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample) = 0; diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index 1acec7ccaf..33714a79b2 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -525,7 +525,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { bool exponent_found = false; bool hexa_found = false; bool sign_found = false; - bool minus_exponent_found = false; bool float_suffix_found = false; String str; @@ -557,8 +556,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { if (sign_found) return _make_token(TK_ERROR, "Invalid numeric constant"); sign_found = true; - if (GETCHAR(i) == '-') - minus_exponent_found = true; } else break; @@ -571,7 +568,7 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { if (hexa_found) { //hex integers eg."0xFF" or "0x12AB", etc - NOT supported yet return _make_token(TK_ERROR, "Invalid (hexadecimal) numeric constant - Not supported"); - } else if (period_found || float_suffix_found) { + } else if (period_found || exponent_found || float_suffix_found) { //floats if (period_found) { if (float_suffix_found) { @@ -614,7 +611,7 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { char_idx += str.length(); Token tk; - if (period_found || minus_exponent_found || float_suffix_found) + if (period_found || exponent_found || float_suffix_found) tk.type = TK_REAL_CONSTANT; else tk.type = TK_INT_CONSTANT; @@ -2078,7 +2075,7 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, OperatorNode *p for (int i = 0; i < argcount; i++) { if (get_scalar_type(args[i]) == args[i] && p_func->arguments[i + 1]->type == Node::TYPE_CONSTANT && convert_constant(static_cast<ConstantNode *>(p_func->arguments[i + 1]), builtin_func_defs[idx].args[i])) { - //all good + //all good, but needs implicit conversion later } else if (args[i] != builtin_func_defs[idx].args[i]) { fail = true; break; @@ -2124,6 +2121,24 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, OperatorNode *p outarg_idx++; } + //implicitly convert values if possible + for (int i = 0; i < argcount; i++) { + + if (get_scalar_type(args[i]) != args[i] || args[i] == builtin_func_defs[idx].args[i] || p_func->arguments[i + 1]->type != Node::TYPE_CONSTANT) { + //can't do implicit conversion here + continue; + } + + //this is an implicit conversion + ConstantNode *constant = static_cast<ConstantNode *>(p_func->arguments[i + 1]); + ConstantNode *conversion = alloc_node<ConstantNode>(); + + conversion->datatype = builtin_func_defs[idx].args[i]; + conversion->values.resize(1); + + convert_constant(constant, builtin_func_defs[idx].args[i], conversion->values.ptrw()); + p_func->arguments.write[i + 1] = conversion; + } if (r_ret_type) *r_ret_type = builtin_func_defs[idx].rettype; @@ -2187,17 +2202,37 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, OperatorNode *p bool fail = false; - for (int i = 0; i < args.size(); i++) { + for (int j = 0; j < args.size(); j++) { - if (get_scalar_type(args[i]) == args[i] && p_func->arguments[i + 1]->type == Node::TYPE_CONSTANT && convert_constant(static_cast<ConstantNode *>(p_func->arguments[i + 1]), pfunc->arguments[i].type)) { - //all good - } else if (args[i] != pfunc->arguments[i].type) { + if (get_scalar_type(args[j]) == args[j] && p_func->arguments[j + 1]->type == Node::TYPE_CONSTANT && convert_constant(static_cast<ConstantNode *>(p_func->arguments[j + 1]), pfunc->arguments[j].type)) { + //all good, but it needs implicit conversion later + } else if (args[j] != pfunc->arguments[j].type) { fail = true; break; } } if (!fail) { + + //implicitly convert values if possible + for (int k = 0; k < args.size(); k++) { + + if (get_scalar_type(args[k]) != args[k] || args[k] == pfunc->arguments[k].type || p_func->arguments[k + 1]->type != Node::TYPE_CONSTANT) { + //can't do implicit conversion here + continue; + } + + //this is an implicit conversion + ConstantNode *constant = static_cast<ConstantNode *>(p_func->arguments[k + 1]); + ConstantNode *conversion = alloc_node<ConstantNode>(); + + conversion->datatype = pfunc->arguments[k].type; + conversion->values.resize(1); + + convert_constant(constant, pfunc->arguments[k].type, conversion->values.ptrw()); + p_func->arguments.write[k + 1] = conversion; + } + if (r_ret_type) *r_ret_type = pfunc->return_type; return true; @@ -2900,7 +2935,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons /* OK now see what's NEXT to the operator.. */ while (true) { - TkPos pos = _get_tkpos(); + TkPos pos2 = _get_tkpos(); tk = _get_token(); if (tk.type == TK_CURSOR) { @@ -3184,7 +3219,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expr = op; } else { - _set_tkpos(pos); + _set_tkpos(pos2); break; } } @@ -3377,10 +3412,10 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons if (!_validate_operator(op, &op->return_cache)) { String at; - for (int i = 0; i < op->arguments.size(); i++) { - if (i > 0) + for (int j = 0; j < op->arguments.size(); j++) { + if (j > 0) at += " and "; - at += get_datatype_name(op->arguments[i]->get_datatype()); + at += get_datatype_name(op->arguments[j]->get_datatype()); } _set_error("Invalid arguments to unary operator '" + get_operator_text(op->op) + "' :" + at); return NULL; @@ -3585,7 +3620,8 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha case TYPE_FLOAT: { nv.real = -cn->values[i].real; } break; - default: {} + default: { + } } values.push_back(nv); @@ -4106,17 +4142,17 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct if (uniform) { - ShaderNode::Uniform uniform; + ShaderNode::Uniform uniform2; if (is_sampler_type(type)) { - uniform.texture_order = texture_uniforms++; - uniform.order = -1; + uniform2.texture_order = texture_uniforms++; + uniform2.order = -1; } else { - uniform.texture_order = -1; - uniform.order = uniforms++; + uniform2.texture_order = -1; + uniform2.order = uniforms++; } - uniform.type = type; - uniform.precission = precision; + uniform2.type = type; + uniform2.precision = precision; //todo parse default value @@ -4127,26 +4163,26 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct tk = _get_token(); if (tk.type == TK_HINT_WHITE_TEXTURE) { - uniform.hint = ShaderNode::Uniform::HINT_WHITE; + uniform2.hint = ShaderNode::Uniform::HINT_WHITE; } else if (tk.type == TK_HINT_BLACK_TEXTURE) { - uniform.hint = ShaderNode::Uniform::HINT_BLACK; + uniform2.hint = ShaderNode::Uniform::HINT_BLACK; } else if (tk.type == TK_HINT_NORMAL_TEXTURE) { - uniform.hint = ShaderNode::Uniform::HINT_NORMAL; + uniform2.hint = ShaderNode::Uniform::HINT_NORMAL; } else if (tk.type == TK_HINT_ANISO_TEXTURE) { - uniform.hint = ShaderNode::Uniform::HINT_ANISO; + uniform2.hint = ShaderNode::Uniform::HINT_ANISO; } else if (tk.type == TK_HINT_ALBEDO_TEXTURE) { - uniform.hint = ShaderNode::Uniform::HINT_ALBEDO; + uniform2.hint = ShaderNode::Uniform::HINT_ALBEDO; } else if (tk.type == TK_HINT_BLACK_ALBEDO_TEXTURE) { - uniform.hint = ShaderNode::Uniform::HINT_BLACK_ALBEDO; + uniform2.hint = ShaderNode::Uniform::HINT_BLACK_ALBEDO; } else if (tk.type == TK_HINT_COLOR) { if (type != TYPE_VEC4) { _set_error("Color hint is for vec4 only"); return ERR_PARSE_ERROR; } - uniform.hint = ShaderNode::Uniform::HINT_COLOR; + uniform2.hint = ShaderNode::Uniform::HINT_COLOR; } else if (tk.type == TK_HINT_RANGE) { - uniform.hint = ShaderNode::Uniform::HINT_RANGE; + uniform2.hint = ShaderNode::Uniform::HINT_RANGE; if (type != TYPE_FLOAT && type != TYPE_INT) { _set_error("Range hint is for float and int only"); return ERR_PARSE_ERROR; @@ -4172,8 +4208,8 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct return ERR_PARSE_ERROR; } - uniform.hint_range[0] = tk.constant; - uniform.hint_range[0] *= sign; + uniform2.hint_range[0] = tk.constant; + uniform2.hint_range[0] *= sign; tk = _get_token(); @@ -4196,8 +4232,8 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct return ERR_PARSE_ERROR; } - uniform.hint_range[1] = tk.constant; - uniform.hint_range[1] *= sign; + uniform2.hint_range[1] = tk.constant; + uniform2.hint_range[1] *= sign; tk = _get_token(); @@ -4209,13 +4245,13 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct return ERR_PARSE_ERROR; } - uniform.hint_range[2] = tk.constant; + uniform2.hint_range[2] = tk.constant; tk = _get_token(); } else { if (type == TYPE_INT) { - uniform.hint_range[2] = 1; + uniform2.hint_range[2] = 1; } else { - uniform.hint_range[2] = 0.001; + uniform2.hint_range[2] = 0.001; } } @@ -4228,7 +4264,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct _set_error("Expected valid type hint after ':'."); } - if (uniform.hint != ShaderNode::Uniform::HINT_RANGE && uniform.hint != ShaderNode::Uniform::HINT_NONE && uniform.hint != ShaderNode::Uniform::HINT_COLOR && type <= TYPE_MAT4) { + if (uniform2.hint != ShaderNode::Uniform::HINT_RANGE && uniform2.hint != ShaderNode::Uniform::HINT_NONE && uniform2.hint != ShaderNode::Uniform::HINT_COLOR && type <= TYPE_MAT4) { _set_error("This hint is only for sampler types"); return ERR_PARSE_ERROR; } @@ -4248,16 +4284,16 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct ConstantNode *cn = static_cast<ConstantNode *>(expr); - uniform.default_value.resize(cn->values.size()); + uniform2.default_value.resize(cn->values.size()); - if (!convert_constant(cn, uniform.type, uniform.default_value.ptrw())) { - _set_error("Can't convert constant to " + get_datatype_name(uniform.type)); + if (!convert_constant(cn, uniform2.type, uniform2.default_value.ptrw())) { + _set_error("Can't convert constant to " + get_datatype_name(uniform2.type)); return ERR_PARSE_ERROR; } tk = _get_token(); } - shader->uniforms[name] = uniform; + shader->uniforms[name] = uniform2; if (tk.type != TK_SEMICOLON) { _set_error("Expected ';'"); @@ -4267,7 +4303,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct ShaderNode::Varying varying; varying.type = type; - varying.precission = precision; + varying.precision = precision; varying.interpolation = interpolation; shader->varyings[name] = varying; @@ -4787,7 +4823,8 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct case TYPE_MAT2: limit = 2; break; case TYPE_MAT3: limit = 3; break; case TYPE_MAT4: limit = 4; break; - default: {} + default: { + } } for (int i = 0; i < limit; i++) { diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h index 2d1851928e..67c273d267 100644 --- a/servers/visual/shader_language.h +++ b/servers/visual/shader_language.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -33,7 +33,7 @@ #include "core/list.h" #include "core/map.h" -#include "core/string_db.h" +#include "core/string_name.h" #include "core/typedefs.h" #include "core/ustring.h" #include "core/variant.h" @@ -42,7 +42,6 @@ class ShaderLanguage { public: enum TokenType { - TK_EMPTY, TK_IDENTIFIER, TK_TRUE, @@ -267,18 +266,15 @@ public: FLOW_OP_SWITCH, FLOW_OP_CONTINUE, FLOW_OP_DISCARD - }; enum ArgumentQualifier { ARGUMENT_QUALIFIER_IN, ARGUMENT_QUALIFIER_OUT, ARGUMENT_QUALIFIER_INOUT, - }; struct Node { - Node *next; enum Type { @@ -296,7 +292,9 @@ public: Type type; virtual DataType get_datatype() const { return TYPE_VOID; } - + Node(Type t) : + next(NULL), + type(t) {} virtual ~Node() {} }; @@ -311,18 +309,17 @@ public: Node *nodes; struct OperatorNode : public Node { - DataType return_cache; DataPrecision return_precision_cache; Operator op; Vector<Node *> arguments; virtual DataType get_datatype() const { return return_cache; } - OperatorNode() { - type = TYPE_OPERATOR; - return_cache = TYPE_VOID; - return_precision_cache = PRECISION_DEFAULT; - } + OperatorNode() : + Node(TYPE_OPERATOR), + return_cache(TYPE_VOID), + return_precision_cache(PRECISION_DEFAULT), + op(OP_EQUAL) {} }; struct VariableNode : public Node { @@ -330,20 +327,16 @@ public: StringName name; virtual DataType get_datatype() const { return datatype_cache; } - VariableNode() { - - type = TYPE_VARIABLE; - datatype_cache = TYPE_VOID; - } + VariableNode() : + Node(TYPE_VARIABLE), + datatype_cache(TYPE_VOID) {} }; struct VariableDeclarationNode : public Node { - DataPrecision precision; DataType datatype; struct Declaration { - StringName name; Node *initializer; }; @@ -351,13 +344,13 @@ public: Vector<Declaration> declarations; virtual DataType get_datatype() const { return datatype; } - VariableDeclarationNode() { - type = TYPE_VARIABLE_DECLARATION; - } + VariableDeclarationNode() : + Node(TYPE_VARIABLE_DECLARATION), + precision(PRECISION_DEFAULT), + datatype(TYPE_VOID) {} }; struct ConstantNode : public Node { - DataType datatype; union Value { @@ -370,7 +363,9 @@ public: Vector<Value> values; virtual DataType get_datatype() const { return datatype; } - ConstantNode() { type = TYPE_CONSTANT; } + ConstantNode() : + Node(TYPE_CONSTANT), + datatype(TYPE_VOID) {} }; struct FunctionNode; @@ -388,39 +383,41 @@ public: Map<StringName, Variable> variables; List<Node *> statements; bool single_statement; - BlockNode() { - type = TYPE_BLOCK; - parent_block = NULL; - parent_function = NULL; - single_statement = false; - } + + BlockNode() : + Node(TYPE_BLOCK), + parent_function(NULL), + parent_block(NULL), + single_statement(false) {} }; struct ControlFlowNode : public Node { - FlowOperation flow_op; Vector<Node *> expressions; Vector<BlockNode *> blocks; - ControlFlowNode() { - type = TYPE_CONTROL_FLOW; - flow_op = FLOW_OP_IF; - } + + ControlFlowNode() : + Node(TYPE_CONTROL_FLOW), + flow_op(FLOW_OP_IF) {} }; struct MemberNode : public Node { - DataType basetype; DataType datatype; StringName name; Node *owner; + virtual DataType get_datatype() const { return datatype; } - MemberNode() { type = TYPE_MEMBER; } + + MemberNode() : + Node(TYPE_MEMBER), + basetype(TYPE_VOID), + datatype(TYPE_VOID), + owner(NULL) {} }; struct FunctionNode : public Node { - struct Argument { - ArgumentQualifier qualifier; StringName name; DataType type; @@ -434,16 +431,15 @@ public: BlockNode *body; bool can_discard; - FunctionNode() { - type = TYPE_FUNCTION; - return_type = TYPE_VOID; - return_precision = PRECISION_DEFAULT; - can_discard = false; - } + FunctionNode() : + Node(TYPE_FUNCTION), + return_type(TYPE_VOID), + return_precision(PRECISION_DEFAULT), + body(NULL), + can_discard(false) {} }; struct ShaderNode : public Node { - struct Function { StringName name; FunctionNode *function; @@ -454,7 +450,12 @@ public: struct Varying { DataType type; DataInterpolation interpolation; - DataPrecision precission; + DataPrecision precision; + + Varying() : + type(TYPE_VOID), + interpolation(INTERPOLATION_FLAT), + precision(PRECISION_DEFAULT) {} }; struct Uniform { @@ -474,16 +475,20 @@ public: int order; int texture_order; DataType type; - DataPrecision precission; + DataPrecision precision; Vector<ConstantNode::Value> default_value; Hint hint; float hint_range[3]; - Uniform() { - hint = HINT_NONE; - hint_range[0] = 0; - hint_range[1] = 1; - hint_range[2] = 0.001; + Uniform() : + order(0), + texture_order(0), + type(TYPE_VOID), + precision(PRECISION_DEFAULT), + hint(HINT_NONE) { + hint_range[0] = 0.0f; + hint_range[1] = 1.0f; + hint_range[2] = 0.001f; } }; @@ -493,11 +498,11 @@ public: Vector<Function> functions; - ShaderNode() { type = TYPE_SHADER; } + ShaderNode() : + Node(TYPE_SHADER) {} }; struct Expression { - bool is_op; union { Operator op; @@ -506,7 +511,6 @@ public: }; struct VarInfo { - StringName name; DataType type; }; @@ -522,7 +526,6 @@ public: }; struct Token { - TokenType type; StringName text; double constant; @@ -556,11 +559,14 @@ public: struct BuiltInInfo { DataType type; bool constant; - BuiltInInfo() {} - BuiltInInfo(DataType p_type, bool p_constant = false) { - type = p_type; - constant = p_constant; - } + + BuiltInInfo() : + type(TYPE_VOID), + constant(false) {} + + BuiltInInfo(DataType p_type, bool p_constant = false) : + type(p_type), + constant(p_constant) {} }; struct FunctionInfo { @@ -573,6 +579,7 @@ private: TokenType token; const char *text; }; + static const KeyWord keyword_list[]; bool error_set; @@ -628,22 +635,18 @@ private: }; bool _find_identifier(const BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type = NULL, IdentifierType *r_type = NULL); - bool _is_operator_assign(Operator p_op) const; bool _validate_assign(Node *p_node, const Map<StringName, BuiltInInfo> &p_builtin_types, String *r_message = NULL); - bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = NULL); struct BuiltinFuncDef { - enum { MAX_ARGS = 5 }; const char *name; DataType rettype; const DataType args[MAX_ARGS]; }; - struct BuiltinFuncOutArgs { //arguments used as out in built in funcions - + struct BuiltinFuncOutArgs { //arguments used as out in built in functions const char *name; int argument; }; @@ -656,20 +659,17 @@ private: int completion_argument; bool _get_completable_identifier(BlockNode *p_block, CompletionType p_type, StringName &identifier); - static const BuiltinFuncDef builtin_func_defs[]; static const BuiltinFuncOutArgs builtin_func_out_args[]; - bool _validate_function_call(BlockNode *p_block, OperatorNode *p_func, DataType *r_ret_type); + bool _validate_function_call(BlockNode *p_block, OperatorNode *p_func, DataType *r_ret_type); bool _parse_function_arguments(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, int *r_complete_arg = NULL); Node *_parse_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types); - ShaderLanguage::Node *_reduce_expression(BlockNode *p_block, ShaderLanguage::Node *p_node); - Node *_parse_and_reduce_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types); + Node *_parse_and_reduce_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types); Error _parse_block(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, bool p_just_one = false, bool p_can_break = false, bool p_can_continue = false); - Error _parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types); public: diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp index baafe2f8d0..7a42bc475e 100644 --- a/servers/visual/shader_types.cpp +++ b/servers/visual/shader_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -60,6 +60,7 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3; shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["TANGENT"] = ShaderLanguage::TYPE_VEC3; shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["BINORMAL"] = ShaderLanguage::TYPE_VEC3; + shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["POSITION"] = ShaderLanguage::TYPE_VEC4; shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["UV"] = ShaderLanguage::TYPE_VEC2; shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["UV2"] = ShaderLanguage::TYPE_VEC2; shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4; @@ -86,6 +87,7 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3; shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["TANGENT"] = ShaderLanguage::TYPE_VEC3; shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["BINORMAL"] = ShaderLanguage::TYPE_VEC3; + shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["VIEW"] = constt(ShaderLanguage::TYPE_VEC3); shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["NORMALMAP"] = ShaderLanguage::TYPE_VEC3; shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["NORMALMAP_DEPTH"] = ShaderLanguage::TYPE_FLOAT; shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["UV"] = constt(ShaderLanguage::TYPE_VEC2); @@ -118,6 +120,7 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["WORLD_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["INV_CAMERA_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); + shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["CAMERA_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["PROJECTION_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["INV_PROJECTION_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); @@ -126,6 +129,7 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["WORLD_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["INV_CAMERA_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); + shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["CAMERA_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["PROJECTION_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["INV_PROJECTION_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); @@ -229,7 +233,7 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_VEC"] = ShaderLanguage::TYPE_VEC2; shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_HEIGHT"] = ShaderLanguage::TYPE_FLOAT; shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_COLOR"] = ShaderLanguage::TYPE_VEC4; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_UV"] = ShaderLanguage::TYPE_VEC2; + shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_UV"] = constt(ShaderLanguage::TYPE_VEC2); shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT"] = ShaderLanguage::TYPE_VEC4; shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["SHADOW_COLOR"] = ShaderLanguage::TYPE_VEC4; shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["POINT_COORD"] = constt(ShaderLanguage::TYPE_VEC2); diff --git a/servers/visual/shader_types.h b/servers/visual/shader_types.h index e195b6ea20..149c9b5e1f 100644 --- a/servers/visual/shader_types.h +++ b/servers/visual/shader_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/servers/visual/visual_server_canvas.cpp b/servers/visual/visual_server_canvas.cpp index 26fb3cc493..15f37dd6d1 100644 --- a/servers/visual/visual_server_canvas.cpp +++ b/servers/visual/visual_server_canvas.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -29,7 +29,7 @@ /*************************************************************************/ #include "visual_server_canvas.h" -#include "visual_server_global.h" +#include "visual_server_globals.h" #include "visual_server_raster.h" #include "visual_server_viewport.h" @@ -55,16 +55,25 @@ void _collect_ysort_children(VisualServerCanvas::Item *p_canvas_item, Transform2 int child_item_count = p_canvas_item->child_items.size(); VisualServerCanvas::Item **child_items = p_canvas_item->child_items.ptrw(); for (int i = 0; i < child_item_count; i++) { - if (r_items) { - r_items[r_index] = child_items[i]; - child_items[i]->ysort_xform = p_transform; - child_items[i]->ysort_pos = p_transform.xform(child_items[i]->xform.elements[2]); - } + if (child_items[i]->visible) { + if (r_items) { + r_items[r_index] = child_items[i]; + child_items[i]->ysort_xform = p_transform; + child_items[i]->ysort_pos = p_transform.xform(child_items[i]->xform.elements[2]); + } + + r_index++; - r_index++; + if (child_items[i]->sort_y) + _collect_ysort_children(child_items[i], p_transform * child_items[i]->xform, r_items, r_index); + } + } +} - if (child_items[i]->sort_y) - _collect_ysort_children(child_items[i], p_transform * child_items[i]->xform, r_items, r_index); +void _mark_ysort_dirty(VisualServerCanvas::Item *ysort_owner, RID_Owner<VisualServerCanvas::Item> &canvas_item_owner) { + while (ysort_owner && ysort_owner->sort_y) { + ysort_owner->ysort_children_count = -1; + ysort_owner = canvas_item_owner.owns(ysort_owner->parent) ? canvas_item_owner.getornull(ysort_owner->parent) : NULL; } } @@ -260,24 +269,24 @@ void VisualServerCanvas::render_canvas(Canvas *p_canvas, const Transform2D &p_tr for (int i = 0; i < l; i++) { - const Canvas::ChildItem &ci = p_canvas->child_items[i]; - _render_canvas_item_tree(ci.item, p_transform, p_clip_rect, p_canvas->modulate, p_lights); + const Canvas::ChildItem &ci2 = p_canvas->child_items[i]; + _render_canvas_item_tree(ci2.item, p_transform, p_clip_rect, p_canvas->modulate, p_lights); //mirroring (useful for scrolling backgrounds) - if (ci.mirror.x != 0) { + if (ci2.mirror.x != 0) { - Transform2D xform2 = p_transform * Transform2D(0, Vector2(ci.mirror.x, 0)); - _render_canvas_item_tree(ci.item, xform2, p_clip_rect, p_canvas->modulate, p_lights); + Transform2D xform2 = p_transform * Transform2D(0, Vector2(ci2.mirror.x, 0)); + _render_canvas_item_tree(ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights); } - if (ci.mirror.y != 0) { + if (ci2.mirror.y != 0) { - Transform2D xform2 = p_transform * Transform2D(0, Vector2(0, ci.mirror.y)); - _render_canvas_item_tree(ci.item, xform2, p_clip_rect, p_canvas->modulate, p_lights); + Transform2D xform2 = p_transform * Transform2D(0, Vector2(0, ci2.mirror.y)); + _render_canvas_item_tree(ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights); } - if (ci.mirror.y != 0 && ci.mirror.x != 0) { + if (ci2.mirror.y != 0 && ci2.mirror.x != 0) { - Transform2D xform2 = p_transform * Transform2D(0, ci.mirror); - _render_canvas_item_tree(ci.item, xform2, p_clip_rect, p_canvas->modulate, p_lights); + Transform2D xform2 = p_transform * Transform2D(0, ci2.mirror); + _render_canvas_item_tree(ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights); } } } @@ -312,6 +321,19 @@ void VisualServerCanvas::canvas_set_modulate(RID p_canvas, const Color &p_color) canvas->modulate = p_color; } +void VisualServerCanvas::canvas_set_disable_scale(bool p_disable) { + disable_scale = p_disable; +} + +void VisualServerCanvas::canvas_set_parent(RID p_canvas, RID p_parent, float p_scale) { + + Canvas *canvas = canvas_owner.get(p_canvas); + ERR_FAIL_COND(!canvas); + + canvas->parent = p_parent; + canvas->parent_scale = p_scale; +} + RID VisualServerCanvas::canvas_item_create() { Item *canvas_item = memnew(Item); @@ -336,11 +358,7 @@ void VisualServerCanvas::canvas_item_set_parent(RID p_item, RID p_parent) { Item *item_owner = canvas_item_owner.get(canvas_item->parent); item_owner->child_items.erase(canvas_item); - Item *ysort_owner = item_owner; - while (ysort_owner && ysort_owner->sort_y) { - item_owner->ysort_children_count = -1; - ysort_owner = canvas_item_owner.owns(ysort_owner->parent) ? canvas_item_owner.getornull(ysort_owner->parent) : NULL; - } + _mark_ysort_dirty(item_owner, canvas_item_owner); } canvas_item->parent = RID(); @@ -360,11 +378,7 @@ void VisualServerCanvas::canvas_item_set_parent(RID p_item, RID p_parent) { item_owner->child_items.push_back(canvas_item); item_owner->children_order_dirty = true; - Item *ysort_owner = item_owner; - while (ysort_owner && ysort_owner->sort_y) { - item_owner->ysort_children_count = -1; - ysort_owner = canvas_item_owner.owns(ysort_owner->parent) ? canvas_item_owner.getornull(ysort_owner->parent) : NULL; - } + _mark_ysort_dirty(item_owner, canvas_item_owner); } else { @@ -381,6 +395,10 @@ void VisualServerCanvas::canvas_item_set_visible(RID p_item, bool p_visible) { ERR_FAIL_COND(!canvas_item); canvas_item->visible = p_visible; + + if (canvas_item->parent.is_valid() && canvas_item_owner.owns(canvas_item->parent)) { + _mark_ysort_dirty(canvas_item_owner.get(canvas_item->parent), canvas_item_owner); + } } void VisualServerCanvas::canvas_item_set_light_mask(RID p_item, int p_mask) { @@ -617,7 +635,7 @@ void VisualServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 &p if (p_tile) { rect->flags |= RasterizerCanvas::CANVAS_RECT_TILE; rect->flags |= RasterizerCanvas::CANVAS_RECT_REGION; - rect->source = Rect2(0, 0, p_rect.size.width, p_rect.size.height); + rect->source = Rect2(0, 0, fabsf(p_rect.size.width), fabsf(p_rect.size.height)); } if (p_rect.size.x < 0) { @@ -759,11 +777,12 @@ void VisualServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); - int ps = p_points.size(); - ERR_FAIL_COND(!p_colors.empty() && p_colors.size() != ps && p_colors.size() != 1); - ERR_FAIL_COND(!p_uvs.empty() && p_uvs.size() != ps); - ERR_FAIL_COND(!p_bones.empty() && p_bones.size() != ps * 4); - ERR_FAIL_COND(!p_weights.empty() && p_weights.size() != ps * 4); + int vertex_count = p_points.size(); + ERR_FAIL_COND(vertex_count == 0); + ERR_FAIL_COND(!p_colors.empty() && p_colors.size() != vertex_count && p_colors.size() != 1); + ERR_FAIL_COND(!p_uvs.empty() && p_uvs.size() != vertex_count); + ERR_FAIL_COND(!p_bones.empty() && p_bones.size() != vertex_count * 4); + ERR_FAIL_COND(!p_weights.empty() && p_weights.size() != vertex_count * 4); Vector<int> indices = p_indices; @@ -771,9 +790,9 @@ void VisualServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector if (indices.empty()) { - ERR_FAIL_COND(ps % 3 != 0); + ERR_FAIL_COND(vertex_count % 3 != 0); if (p_count == -1) - count = ps; + count = vertex_count; } else { ERR_FAIL_COND(indices.size() % 3 != 0); @@ -873,7 +892,8 @@ void VisualServerCanvas::canvas_item_set_sort_children_by_y(RID p_item, bool p_e ERR_FAIL_COND(!canvas_item); canvas_item->sort_y = p_enable; - canvas_item->ysort_children_count = -1; + + _mark_ysort_dirty(canvas_item, canvas_item_owner); } void VisualServerCanvas::canvas_item_set_z_index(RID p_item, int p_z) { @@ -1351,11 +1371,7 @@ bool VisualServerCanvas::free(RID p_rid) { Item *item_owner = canvas_item_owner.get(canvas_item->parent); item_owner->child_items.erase(canvas_item); - Item *ysort_owner = item_owner; - while (ysort_owner && ysort_owner->sort_y) { - item_owner->ysort_children_count = -1; - ysort_owner = canvas_item_owner.owns(ysort_owner->parent) ? canvas_item_owner.getornull(ysort_owner->parent) : NULL; - } + _mark_ysort_dirty(item_owner, canvas_item_owner); } } @@ -1437,4 +1453,5 @@ bool VisualServerCanvas::free(RID p_rid) { } VisualServerCanvas::VisualServerCanvas() { + disable_scale = false; } diff --git a/servers/visual/visual_server_canvas.h b/servers/visual/visual_server_canvas.h index 4b7422b15a..8162085ced 100644 --- a/servers/visual/visual_server_canvas.h +++ b/servers/visual/visual_server_canvas.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -126,6 +126,8 @@ public: bool children_order_dirty; Vector<ChildItem> child_items; Color modulate; + RID parent; + float parent_scale; int find_item(Item *p_item) { for (int i = 0; i < child_items.size(); i++) { @@ -143,13 +145,16 @@ public: Canvas() { modulate = Color(1, 1, 1, 1); children_order_dirty = true; + parent_scale = 1.0; } }; - RID_Owner<Canvas> canvas_owner; + mutable RID_Owner<Canvas> canvas_owner; RID_Owner<Item> canvas_item_owner; RID_Owner<RasterizerCanvas::Light> canvas_light_owner; + bool disable_scale; + private: void _render_canvas_item_tree(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights); void _render_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RasterizerCanvas::Item **z_list, RasterizerCanvas::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner); @@ -161,6 +166,8 @@ public: RID canvas_create(); void canvas_set_item_mirroring(RID p_canvas, RID p_item, const Point2 &p_mirroring); void canvas_set_modulate(RID p_canvas, const Color &p_color); + void canvas_set_parent(RID p_canvas, RID p_parent, float p_scale); + void canvas_set_disable_scale(bool p_disable); RID canvas_item_create(); void canvas_item_set_parent(RID p_item, RID p_parent); diff --git a/servers/visual/visual_server_global.cpp b/servers/visual/visual_server_globals.cpp index 61a8951f75..5c247c7f0f 100644 --- a/servers/visual/visual_server_global.cpp +++ b/servers/visual/visual_server_globals.cpp @@ -1,12 +1,12 @@ /*************************************************************************/ -/* visual_server_global.cpp */ +/* visual_server_globals.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "visual_server_global.h" +#include "visual_server_globals.h" RasterizerStorage *VisualServerGlobals::storage = NULL; RasterizerCanvas *VisualServerGlobals::canvas_render = NULL; diff --git a/servers/visual/visual_server_global.h b/servers/visual/visual_server_globals.h index b4888dfd50..04d52aa1eb 100644 --- a/servers/visual/visual_server_global.h +++ b/servers/visual/visual_server_globals.h @@ -1,12 +1,12 @@ /*************************************************************************/ -/* visual_server_global.h */ +/* visual_server_globals.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef VISUALSERVERGLOBAL_H -#define VISUALSERVERGLOBAL_H +#ifndef VISUAL_SERVER_GLOBALS_H +#define VISUAL_SERVER_GLOBALS_H #include "rasterizer.h" @@ -51,4 +51,4 @@ public: #define VSG VisualServerGlobals -#endif // VISUALSERVERGLOBAL_H +#endif // VISUAL_SERVER_GLOBALS_H diff --git a/servers/visual/visual_server_light_baker.cpp b/servers/visual/visual_server_light_baker.cpp index ed87e84a03..5626a72283 100644 --- a/servers/visual/visual_server_light_baker.cpp +++ b/servers/visual/visual_server_light_baker.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/servers/visual/visual_server_light_baker.h b/servers/visual/visual_server_light_baker.h index 77472d0994..6e1148d622 100644 --- a/servers/visual/visual_server_light_baker.h +++ b/servers/visual/visual_server_light_baker.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 677c323216..a9ca920178 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -33,9 +33,9 @@ #include "core/io/marshalls.h" #include "core/os/os.h" #include "core/project_settings.h" -#include "core/sort.h" +#include "core/sort_array.h" #include "visual_server_canvas.h" -#include "visual_server_global.h" +#include "visual_server_globals.h" #include "visual_server_scene.h" // careful, these may run in different threads than the visual server @@ -123,7 +123,6 @@ void VisualServerRaster::draw(bool p_swap_buffers, double frame_step) { frame_drawn_callbacks.pop_front(); } - VS::get_singleton()->emit_signal("frame_post_draw"); } void VisualServerRaster::sync() { diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index f3a442be99..8ce25ba906 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -31,12 +31,11 @@ #ifndef VISUAL_SERVER_RASTER_H #define VISUAL_SERVER_RASTER_H -#include "core/allocators.h" #include "core/math/octree.h" #include "servers/visual/rasterizer.h" #include "servers/visual_server.h" #include "visual_server_canvas.h" -#include "visual_server_global.h" +#include "visual_server_globals.h" #include "visual_server_scene.h" #include "visual_server_viewport.h" /** @@ -297,6 +296,7 @@ public: BIND3(skeleton_bone_set_transform_2d, RID, int, const Transform2D &) BIND2RC(Transform2D, skeleton_bone_get_transform_2d, RID, int) BIND2(skeleton_set_base_transform_2d, RID, const Transform2D &) + BIND3(skeleton_set_world_transform, RID, bool, const Transform &) /* Light API */ @@ -495,6 +495,7 @@ public: BIND2(environment_set_background, RID, EnvironmentBG) BIND2(environment_set_sky, RID, RID) BIND2(environment_set_sky_custom_fov, RID, float) + BIND2(environment_set_sky_orientation, RID, const Basis &) BIND2(environment_set_bg_color, RID, const Color &) BIND2(environment_set_bg_energy, RID, float) BIND2(environment_set_canvas_max_layer, RID, int) @@ -568,6 +569,8 @@ public: BIND0R(RID, canvas_create) BIND3(canvas_set_item_mirroring, RID, RID, const Point2 &) BIND2(canvas_set_modulate, RID, const Color &) + BIND3(canvas_set_parent, RID, RID, float) + BIND1(canvas_set_disable_scale, bool) BIND0R(RID, canvas_item_create) BIND2(canvas_item_set_parent, RID, RID) diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index 1deca7bc66..a5858ab661 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,8 +30,9 @@ #include "visual_server_scene.h" #include "core/os/os.h" -#include "visual_server_global.h" +#include "visual_server_globals.h" #include "visual_server_raster.h" +#include <new> /* CAMERA API */ RID VisualServerScene::camera_create() { @@ -398,7 +399,8 @@ void VisualServerScene::instance_set_base(RID p_instance, RID p_base) { VSG::scene_render->free(gi_probe->probe_instance); } break; - default: {} + default: { + } } if (instance->base_data) { @@ -444,6 +446,9 @@ void VisualServerScene::instance_set_base(RID p_instance, RID p_base) { InstanceGeometryData *geom = memnew(InstanceGeometryData); instance->base_data = geom; + if (instance->base_type == VS::INSTANCE_MESH) { + instance->blend_values.resize(VSG::storage->mesh_get_blend_shape_count(p_base)); + } } break; case VS::INSTANCE_REFLECTION_PROBE: { @@ -472,7 +477,8 @@ void VisualServerScene::instance_set_base(RID p_instance, RID p_base) { gi_probe->probe_instance = VSG::scene_render->gi_probe_instance_create(); } break; - default: {} + default: { + } } VSG::storage->instance_add_dependency(p_base, instance); @@ -520,7 +526,8 @@ void VisualServerScene::instance_set_scenario(RID p_instance, RID p_scenario) { gi_probe_update_list.remove(&gi_probe->update_element); } } break; - default: {} + default: { + } } instance->scenario = NULL; @@ -552,7 +559,8 @@ void VisualServerScene::instance_set_scenario(RID p_instance, RID p_scenario) { gi_probe_update_list.add(&gi_probe->update_element); } } break; - default: {} + default: { + } } _instance_queue_update(instance, true, true); @@ -573,6 +581,19 @@ void VisualServerScene::instance_set_transform(RID p_instance, const Transform & if (instance->transform == p_transform) return; //must be checked to avoid worst evil +#ifdef DEBUG_ENABLED + + for (int i = 0; i < 4; i++) { + const Vector3 &v = i < 3 ? p_transform.basis.elements[i] : p_transform.origin; + ERR_FAIL_COND(Math::is_inf(v.x)); + ERR_FAIL_COND(Math::is_nan(v.x)); + ERR_FAIL_COND(Math::is_inf(v.y)); + ERR_FAIL_COND(Math::is_nan(v.y)); + ERR_FAIL_COND(Math::is_inf(v.z)); + ERR_FAIL_COND(Math::is_nan(v.z)); + } + +#endif instance->transform = p_transform; _instance_queue_update(instance, true); } @@ -654,7 +675,8 @@ void VisualServerScene::instance_set_visible(RID p_instance, bool p_visible) { } } break; - default: {} + default: { + } } } inline bool is_geometry_instance(VisualServer::InstanceType p_type) { @@ -831,7 +853,8 @@ void VisualServerScene::instance_geometry_set_flag(RID p_instance, VS::InstanceF instance->redraw_if_visible = p_enabled; } break; - default: {} + default: { + } } } void VisualServerScene::instance_geometry_set_cast_shadows_setting(RID p_instance, VS::ShadowCastingSetting p_shadow_casting_setting) { @@ -1023,7 +1046,8 @@ void VisualServerScene::_update_instance_aabb(Instance *p_instance) { new_aabb = VSG::storage->lightmap_capture_get_bounds(p_instance->base); } break; - default: {} + default: { + } } // <Zylann> This is why I didn't re-use Instance::aabb to implement custom AABBs @@ -1240,7 +1264,9 @@ void VisualServerScene::_update_instance_lightmap_captures(Instance *p_instance) //print_line("update captures for pos: " + p_instance->transform.origin); - zeromem(p_instance->lightmap_capture_data.ptrw(), 12 * sizeof(Color)); + for (int i = 0; i < 12; i++) + new (&p_instance->lightmap_capture_data.ptrw()[i]) Color; + //this could use some sort of blending.. for (List<Instance *>::Element *E = geom->lightmap_captures.front(); E; E = E->next()) { const PoolVector<RasterizerStorage::LightmapCaptureOctree> *octree = VSG::storage->lightmap_capture_get_octree_ptr(E->get()->base); @@ -1535,106 +1561,102 @@ bool VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons VS::LightOmniShadowMode shadow_mode = VSG::storage->light_omni_get_shadow_mode(p_instance->base); - switch (shadow_mode) { - case VS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID: { - - for (int i = 0; i < 2; i++) { - - //using this one ensures that raster deferred will have it + if (shadow_mode == VS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID || !VSG::scene_render->light_instances_can_render_shadow_cube()) { - float radius = VSG::storage->light_get_param(p_instance->base, VS::LIGHT_PARAM_RANGE); + for (int i = 0; i < 2; i++) { - float z = i == 0 ? -1 : 1; - Vector<Plane> planes; - planes.resize(5); - planes.write[0] = light_transform.xform(Plane(Vector3(0, 0, z), radius)); - planes.write[1] = light_transform.xform(Plane(Vector3(1, 0, z).normalized(), radius)); - planes.write[2] = light_transform.xform(Plane(Vector3(-1, 0, z).normalized(), radius)); - planes.write[3] = light_transform.xform(Plane(Vector3(0, 1, z).normalized(), radius)); - planes.write[4] = light_transform.xform(Plane(Vector3(0, -1, z).normalized(), radius)); + //using this one ensures that raster deferred will have it - int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, VS::INSTANCE_GEOMETRY_MASK); - Plane near_plane(light_transform.origin, light_transform.basis.get_axis(2) * z); - - for (int j = 0; j < cull_count; j++) { - - Instance *instance = instance_shadow_cull_result[j]; - if (!instance->visible || !((1 << instance->base_type) & VS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) { - cull_count--; - SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]); - j--; - } else { - if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) { - animated_material_found = true; - } + float radius = VSG::storage->light_get_param(p_instance->base, VS::LIGHT_PARAM_RANGE); - instance->depth = near_plane.distance_to(instance->transform.origin); - instance->depth_layer = 0; + float z = i == 0 ? -1 : 1; + Vector<Plane> planes; + planes.resize(5); + planes.write[0] = light_transform.xform(Plane(Vector3(0, 0, z), radius)); + planes.write[1] = light_transform.xform(Plane(Vector3(1, 0, z).normalized(), radius)); + planes.write[2] = light_transform.xform(Plane(Vector3(-1, 0, z).normalized(), radius)); + planes.write[3] = light_transform.xform(Plane(Vector3(0, 1, z).normalized(), radius)); + planes.write[4] = light_transform.xform(Plane(Vector3(0, -1, z).normalized(), radius)); + + int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, VS::INSTANCE_GEOMETRY_MASK); + Plane near_plane(light_transform.origin, light_transform.basis.get_axis(2) * z); + + for (int j = 0; j < cull_count; j++) { + + Instance *instance = instance_shadow_cull_result[j]; + if (!instance->visible || !((1 << instance->base_type) & VS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) { + cull_count--; + SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]); + j--; + } else { + if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) { + animated_material_found = true; } - } - VSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, i); - VSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count); + instance->depth = near_plane.distance_to(instance->transform.origin); + instance->depth_layer = 0; + } } - } break; - case VS::LIGHT_OMNI_SHADOW_CUBE: { - - float radius = VSG::storage->light_get_param(p_instance->base, VS::LIGHT_PARAM_RANGE); - CameraMatrix cm; - cm.set_perspective(90, 1, 0.01, radius); - - for (int i = 0; i < 6; i++) { - - //using this one ensures that raster deferred will have it - static const Vector3 view_normals[6] = { - Vector3(-1, 0, 0), - Vector3(+1, 0, 0), - Vector3(0, -1, 0), - Vector3(0, +1, 0), - Vector3(0, 0, -1), - Vector3(0, 0, +1) - }; - static const Vector3 view_up[6] = { - Vector3(0, -1, 0), - Vector3(0, -1, 0), - Vector3(0, 0, -1), - Vector3(0, 0, +1), - Vector3(0, -1, 0), - Vector3(0, -1, 0) - }; - - Transform xform = light_transform * Transform().looking_at(view_normals[i], view_up[i]); - - Vector<Plane> planes = cm.get_projection_planes(xform); + VSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, i); + VSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count); + } + } else { //shadow cube - int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, VS::INSTANCE_GEOMETRY_MASK); + float radius = VSG::storage->light_get_param(p_instance->base, VS::LIGHT_PARAM_RANGE); + CameraMatrix cm; + cm.set_perspective(90, 1, 0.01, radius); - Plane near_plane(xform.origin, -xform.basis.get_axis(2)); - for (int j = 0; j < cull_count; j++) { + for (int i = 0; i < 6; i++) { - Instance *instance = instance_shadow_cull_result[j]; - if (!instance->visible || !((1 << instance->base_type) & VS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) { - cull_count--; - SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]); - j--; - } else { - if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) { - animated_material_found = true; - } - instance->depth = near_plane.distance_to(instance->transform.origin); - instance->depth_layer = 0; + //using this one ensures that raster deferred will have it + + static const Vector3 view_normals[6] = { + Vector3(-1, 0, 0), + Vector3(+1, 0, 0), + Vector3(0, -1, 0), + Vector3(0, +1, 0), + Vector3(0, 0, -1), + Vector3(0, 0, +1) + }; + static const Vector3 view_up[6] = { + Vector3(0, -1, 0), + Vector3(0, -1, 0), + Vector3(0, 0, -1), + Vector3(0, 0, +1), + Vector3(0, -1, 0), + Vector3(0, -1, 0) + }; + + Transform xform = light_transform * Transform().looking_at(view_normals[i], view_up[i]); + + Vector<Plane> planes = cm.get_projection_planes(xform); + + int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, VS::INSTANCE_GEOMETRY_MASK); + + Plane near_plane(xform.origin, -xform.basis.get_axis(2)); + for (int j = 0; j < cull_count; j++) { + + Instance *instance = instance_shadow_cull_result[j]; + if (!instance->visible || !((1 << instance->base_type) & VS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) { + cull_count--; + SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]); + j--; + } else { + if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) { + animated_material_found = true; } + instance->depth = near_plane.distance_to(instance->transform.origin); + instance->depth_layer = 0; } - - VSG::scene_render->light_instance_set_shadow_transform(light->instance, cm, xform, radius, 0, i); - VSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count); } - //restore the regular DP matrix - VSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, 0); + VSG::scene_render->light_instance_set_shadow_transform(light->instance, cm, xform, radius, 0, i); + VSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count); + } - } break; + //restore the regular DP matrix + VSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, 0); } } break; @@ -2468,7 +2490,7 @@ void VisualServerScene::_setup_gi_probe(Instance *p_instance) { uint32_t a = uint32_t(alpha_block[x][y]) - min_alpha; //convert range to 3 bits a = int((a * 7.0 / (max_alpha - min_alpha)) + 0.5); - a = CLAMP(a, 0, 7); //just to be sure + a = MIN(a, 7); //just to be sure a = 7 - a; //because range is inverted in this mode if (a == 0) { //do none, remain @@ -2904,7 +2926,7 @@ void VisualServerScene::_bake_gi_probe(Instance *p_gi_probe) { uint32_t idx = level_cells[j]; - uint32_t r = (uint32_t(local_data[idx].energy[0]) / probe_data->dynamic.bake_dynamic_range) >> 2; + uint32_t r2 = (uint32_t(local_data[idx].energy[0]) / probe_data->dynamic.bake_dynamic_range) >> 2; uint32_t g = (uint32_t(local_data[idx].energy[1]) / probe_data->dynamic.bake_dynamic_range) >> 2; uint32_t b = (uint32_t(local_data[idx].energy[2]) / probe_data->dynamic.bake_dynamic_range) >> 2; uint32_t a = (cells[idx].level_alpha >> 8) & 0xFF; @@ -2912,10 +2934,10 @@ void VisualServerScene::_bake_gi_probe(Instance *p_gi_probe) { uint32_t mm_ofs = sizes[0] * sizes[1] * (local_data[idx].pos[2]) + sizes[0] * (local_data[idx].pos[1]) + (local_data[idx].pos[0]); mm_ofs *= 4; //for RGBA (4 bytes) - mipmapw[mm_ofs + 0] = uint8_t(CLAMP(r, 0, 255)); - mipmapw[mm_ofs + 1] = uint8_t(CLAMP(g, 0, 255)); - mipmapw[mm_ofs + 2] = uint8_t(CLAMP(b, 0, 255)); - mipmapw[mm_ofs + 3] = uint8_t(CLAMP(a, 0, 255)); + mipmapw[mm_ofs + 0] = uint8_t(MIN(r2, 255)); + mipmapw[mm_ofs + 1] = uint8_t(MIN(g, 255)); + mipmapw[mm_ofs + 2] = uint8_t(MIN(b, 255)); + mipmapw[mm_ofs + 3] = uint8_t(MIN(a, 255)); } } } else if (probe_data->dynamic.compression == RasterizerStorage::GI_PROBE_S3TC) { diff --git a/servers/visual/visual_server_scene.h b/servers/visual/visual_server_scene.h index 38c5258116..7583acd88f 100644 --- a/servers/visual/visual_server_scene.h +++ b/servers/visual/visual_server_scene.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -33,7 +33,6 @@ #include "servers/visual/rasterizer.h" -#include "core/allocators.h" #include "core/math/geometry.h" #include "core/math/octree.h" #include "core/os/semaphore.h" @@ -120,7 +119,6 @@ public: VS::ScenarioDebugMode debug; RID self; - // well wtf, balloon allocator is slower? Octree<Instance, true> octree; diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp index 571b71db85..e7f60c2c1f 100644 --- a/servers/visual/visual_server_viewport.cpp +++ b/servers/visual/visual_server_viewport.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,9 +32,46 @@ #include "core/project_settings.h" #include "visual_server_canvas.h" -#include "visual_server_global.h" +#include "visual_server_globals.h" #include "visual_server_scene.h" +static Transform2D _canvas_get_transform(VisualServerViewport::Viewport *p_viewport, VisualServerCanvas::Canvas *p_canvas, VisualServerViewport::Viewport::CanvasData *p_canvas_data, const Vector2 &p_vp_size) { + + Transform2D xf = p_viewport->global_transform; + + float scale = 1.0; + if (p_viewport->canvas_map.has(p_canvas->parent)) { + xf = xf * p_viewport->canvas_map[p_canvas->parent].transform; + scale = p_canvas->parent_scale; + } + + xf = xf * p_canvas_data->transform; + + if (scale != 1.0 && !VSG::canvas->disable_scale) { + Vector2 pivot = p_vp_size * 0.5; + Transform2D xfpivot; + xfpivot.set_origin(pivot); + Transform2D xfscale; + xfscale.scale(Vector2(scale, scale)); + + xf = xfpivot.affine_inverse() * xf; + xf = xfscale * xf; + xf = xfpivot * xf; + } + + return xf; +} + +void VisualServerViewport::_draw_3d(Viewport *p_viewport, ARVRInterface::Eyes p_eye) { + Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface(); + + if (p_viewport->use_arvr && arvr_interface.is_valid()) { + VSG::scene->render_camera(arvr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); + } else { + VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); + } +} + void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::Eyes p_eye) { /* Camera should always be BEFORE any other 3D */ @@ -62,13 +99,7 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E } if (!scenario_draw_canvas_bg && can_draw_3d) { - Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface(); - - if (p_viewport->use_arvr && arvr_interface.is_valid()) { - VSG::scene->render_camera(arvr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); - } else { - VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); - } + _draw_3d(p_viewport, p_eye); } if (!p_viewport->hide_canvas) { @@ -86,10 +117,10 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { - Transform2D xf = p_viewport->global_transform * E->get().transform; - VisualServerCanvas::Canvas *canvas = static_cast<VisualServerCanvas::Canvas *>(E->get().canvas); + Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size); + //find lights in canvas for (Set<RasterizerCanvas::Light *>::Element *F = canvas->lights.front(); F; F = F->next()) { @@ -97,7 +128,7 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E RasterizerCanvas::Light *cl = F->get(); if (cl->enabled && cl->texture.is_valid()) { //not super efficient.. - Size2 tsize(VSG::storage->texture_get_width(cl->texture), VSG::storage->texture_get_height(cl->texture)); + Size2 tsize = VSG::storage->texture_size_with_proxy(cl->texture); tsize *= cl->scale; Vector2 offset = tsize / 2.0; @@ -167,24 +198,20 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E RasterizerCanvas::Light *light = lights_with_shadow; while (light) { - VSG::canvas_render->canvas_light_shadow_buffer_update(light->shadow_buffer, light->xform_cache.affine_inverse(), light->item_mask, light->radius_cache / 1000.0, light->radius_cache * 1.1, occluders, &light->shadow_matrix_cache); + VSG::canvas_render->canvas_light_shadow_buffer_update(light->shadow_buffer, light->xform_cache.affine_inverse(), light->item_shadow_mask, light->radius_cache / 1000.0, light->radius_cache * 1.1, occluders, &light->shadow_matrix_cache); light = light->shadows_next_ptr; } //VSG::canvas_render->reset_canvas(); } - VSG::rasterizer->restore_render_target(); + VSG::rasterizer->restore_render_target(!scenario_draw_canvas_bg && can_draw_3d); if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().get_layer() > scenario_canvas_max_layer) { - Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface(); - if (!can_draw_3d) { VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas); - } else if (p_viewport->use_arvr && arvr_interface.is_valid()) { - VSG::scene->render_camera(arvr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); } else { - VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); + _draw_3d(p_viewport, p_eye); } scenario_draw_canvas_bg = false; } @@ -193,7 +220,7 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E VisualServerCanvas::Canvas *canvas = static_cast<VisualServerCanvas::Canvas *>(E->get()->canvas); - Transform2D xform = p_viewport->global_transform * E->get()->transform; + Transform2D xform = _canvas_get_transform(p_viewport, canvas, E->get(), clip_rect.size); RasterizerCanvas::Light *canvas_lights = NULL; @@ -210,14 +237,10 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E i++; if (scenario_draw_canvas_bg && E->key().get_layer() >= scenario_canvas_max_layer) { - Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface(); - if (!can_draw_3d) { VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas); - } else if (p_viewport->use_arvr && arvr_interface.is_valid()) { - VSG::scene->render_camera(arvr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); } else { - VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); + _draw_3d(p_viewport, p_eye); } scenario_draw_canvas_bg = false; @@ -225,14 +248,10 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E } if (scenario_draw_canvas_bg) { - Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface(); - if (!can_draw_3d) { VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas); - } else if (p_viewport->use_arvr && arvr_interface.is_valid()) { - VSG::scene->render_camera(arvr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); } else { - VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); + _draw_3d(p_viewport, p_eye); } scenario_draw_canvas_bg = false; @@ -276,17 +295,27 @@ void VisualServerViewport::draw_viewports() { if (vp->use_arvr && arvr_interface.is_valid()) { // override our size, make sure it matches our required size - Size2 size = arvr_interface->get_render_targetsize(); - VSG::storage->render_target_set_size(vp->render_target, size.x, size.y); + vp->size = arvr_interface->get_render_targetsize(); + VSG::storage->render_target_set_size(vp->render_target, vp->size.x, vp->size.y); // render mono or left eye first ARVRInterface::Eyes leftOrMono = arvr_interface->is_stereo() ? ARVRInterface::EYE_LEFT : ARVRInterface::EYE_MONO; + + // check for an external texture destination for our left eye/mono + VSG::storage->render_target_set_external_texture(vp->render_target, arvr_interface->get_external_texture_for_eye(leftOrMono)); + + // set our render target as current VSG::rasterizer->set_current_render_target(vp->render_target); + + // and draw left eye/mono _draw_viewport(vp, leftOrMono); arvr_interface->commit_for_eye(leftOrMono, vp->render_target, vp->viewport_to_screen_rect); // render right eye if (leftOrMono == ARVRInterface::EYE_LEFT) { + // check for an external texture destination for our right eye + VSG::storage->render_target_set_external_texture(vp->render_target, arvr_interface->get_external_texture_for_eye(ARVRInterface::EYE_RIGHT)); + // commit for eye may have changed the render target VSG::rasterizer->set_current_render_target(vp->render_target); @@ -297,6 +326,7 @@ void VisualServerViewport::draw_viewports() { // and for our frame timing, mark when we've finished committing our eyes ARVRServer::get_singleton()->_mark_commit(); } else { + VSG::storage->render_target_set_external_texture(vp->render_target, 0); VSG::rasterizer->set_current_render_target(vp->render_target); VSG::scene_render->set_debug_draw_mode(vp->debug_draw); diff --git a/servers/visual/visual_server_viewport.h b/servers/visual/visual_server_viewport.h index 66baa48458..555b40a103 100644 --- a/servers/visual/visual_server_viewport.h +++ b/servers/visual/visual_server_viewport.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -90,7 +90,8 @@ public: } CanvasKey(const RID &p_canvas, int p_layer, int p_sublayer) { canvas = p_canvas; - stacking = ((int64_t)p_layer << 32) + p_sublayer; + int64_t sign = p_layer < 0 ? -1 : 1; + stacking = sign * (((int64_t)ABS(p_layer)) << 32) + p_sublayer; } int get_layer() const { return stacking >> 32; } }; @@ -146,6 +147,7 @@ public: private: Color clear_color; + void _draw_3d(Viewport *p_viewport, ARVRInterface::Eyes p_eye); void _draw_viewport(Viewport *p_viewport, ARVRInterface::Eyes p_eye = ARVRInterface::EYE_MONO); public: diff --git a/servers/visual/visual_server_wrap_mt.cpp b/servers/visual/visual_server_wrap_mt.cpp index f59d8af9cb..79e4d8cbba 100644 --- a/servers/visual/visual_server_wrap_mt.cpp +++ b/servers/visual/visual_server_wrap_mt.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 37f6323b8f..efe251e9de 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -232,6 +232,7 @@ public: FUNC3(skeleton_bone_set_transform_2d, RID, int, const Transform2D &) FUNC2RC(Transform2D, skeleton_bone_get_transform_2d, RID, int) FUNC2(skeleton_set_base_transform_2d, RID, const Transform2D &) + FUNC3(skeleton_set_world_transform, RID, bool, const Transform &) /* Light API */ @@ -421,6 +422,7 @@ public: FUNC2(environment_set_background, RID, EnvironmentBG) FUNC2(environment_set_sky, RID, RID) FUNC2(environment_set_sky_custom_fov, RID, float) + FUNC2(environment_set_sky_orientation, RID, const Basis &) FUNC2(environment_set_bg_color, RID, const Color &) FUNC2(environment_set_bg_energy, RID, float) FUNC2(environment_set_canvas_max_layer, RID, int) @@ -485,6 +487,8 @@ public: FUNCRID(canvas) FUNC3(canvas_set_item_mirroring, RID, RID, const Point2 &) FUNC2(canvas_set_modulate, RID, const Color &) + FUNC3(canvas_set_parent, RID, RID, float) + FUNC1(canvas_set_disable_scale, bool) FUNCRID(canvas_item) FUNC2(canvas_item_set_parent, RID, RID) |