diff options
80 files changed, 1580 insertions, 989 deletions
diff --git a/core/math/math_funcs.cpp b/core/math/math_funcs.cpp index 1585c96b38..4154713a87 100644 --- a/core/math/math_funcs.cpp +++ b/core/math/math_funcs.cpp @@ -34,8 +34,6 @@ RandomPCG Math::default_rand(RandomPCG::DEFAULT_SEED, RandomPCG::DEFAULT_INC); -#define PHI 0x9e3779b9 - uint32_t Math::rand_from_seed(uint64_t *seed) { RandomPCG rng = RandomPCG(*seed, RandomPCG::DEFAULT_INC); uint32_t r = rng.rand(); diff --git a/core/math/random_number_generator.cpp b/core/math/random_number_generator.cpp index 67f4c0b14a..a124f63030 100644 --- a/core/math/random_number_generator.cpp +++ b/core/math/random_number_generator.cpp @@ -33,7 +33,6 @@ void RandomNumberGenerator::_bind_methods() { ClassDB::bind_method(D_METHOD("set_seed", "seed"), &RandomNumberGenerator::set_seed); ClassDB::bind_method(D_METHOD("get_seed"), &RandomNumberGenerator::get_seed); - ADD_PROPERTY(PropertyInfo(Variant::INT, "seed"), "set_seed", "get_seed"); ClassDB::bind_method(D_METHOD("randi"), &RandomNumberGenerator::randi); ClassDB::bind_method(D_METHOD("randf"), &RandomNumberGenerator::randf); @@ -41,4 +40,8 @@ void RandomNumberGenerator::_bind_methods() { ClassDB::bind_method(D_METHOD("randf_range", "from", "to"), &RandomNumberGenerator::randf_range); ClassDB::bind_method(D_METHOD("randi_range", "from", "to"), &RandomNumberGenerator::randi_range); ClassDB::bind_method(D_METHOD("randomize"), &RandomNumberGenerator::randomize); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "seed"), "set_seed", "get_seed"); + // Default value is non-deterministic, override it for doc generation purposes. + ADD_PROPERTY_DEFAULT("seed", 0); } diff --git a/core/math/rect2.h b/core/math/rect2.h index 7660db71eb..5a746aa732 100644 --- a/core/math/rect2.h +++ b/core/math/rect2.h @@ -244,6 +244,68 @@ struct Rect2 { return Rect2(Point2(position.x + MIN(size.x, 0), position.y + MIN(size.y, 0)), size.abs()); } + Vector2 get_support(const Vector2 &p_normal) const { + Vector2 half_extents = size * 0.5; + Vector2 ofs = position + half_extents; + return Vector2( + (p_normal.x > 0) ? -half_extents.x : half_extents.x, + (p_normal.y > 0) ? -half_extents.y : half_extents.y) + + ofs; + } + + _FORCE_INLINE_ bool intersects_filled_polygon(const Vector2 *p_points, int p_point_count) const { + Vector2 center = position + size * 0.5; + int side_plus = 0; + int side_minus = 0; + Vector2 end = position + size; + + int i_f = p_point_count - 1; + for (int i = 0; i < p_point_count; i++) { + const Vector2 &a = p_points[i_f]; + const Vector2 &b = p_points[i]; + i_f = i; + + Vector2 r = (b - a); + float l = r.length(); + if (l == 0.0) { + continue; + } + + //check inside + Vector2 tg = r.tangent(); + float s = tg.dot(center) - tg.dot(a); + if (s < 0.0) { + side_plus++; + } else { + side_minus++; + } + + //check ray box + r /= l; + Vector2 ir(1.0 / r.x, 1.0 / r.y); + + // lb is the corner of AABB with minimal coordinates - left bottom, rt is maximal corner + // r.org is origin of ray + Vector2 t13 = (position - a) * ir; + Vector2 t24 = (end - a) * ir; + + float tmin = MAX(MIN(t13.x, t24.x), MIN(t13.y, t24.y)); + float tmax = MIN(MAX(t13.x, t24.x), MAX(t13.y, t24.y)); + + // if tmax < 0, ray (line) is intersecting AABB, but the whole AABB is behind us + if (tmax < 0 || tmin > tmax || tmin >= l) { + continue; + } + + return true; + } + + if (side_plus * side_minus == 0) { + return true; //all inside + } else { + return false; + } + } operator String() const { return String(position) + ", " + String(size); } Rect2() {} @@ -305,8 +367,8 @@ struct Rect2i { new_rect.position.x = MAX(p_rect.position.x, position.x); new_rect.position.y = MAX(p_rect.position.y, position.y); - Point2 p_rect_end = p_rect.position + p_rect.size; - Point2 end = position + size; + Point2i p_rect_end = p_rect.position + p_rect.size; + Point2i end = position + size; new_rect.size.x = (int)(MIN(p_rect_end.x, end.x) - new_rect.position.x); new_rect.size.y = (int)(MIN(p_rect_end.y, end.y) - new_rect.position.y); @@ -328,7 +390,7 @@ struct Rect2i { return new_rect; } - bool has_point(const Point2 &p_point) const { + bool has_point(const Point2i &p_point) const { if (p_point.x < position.x) { return false; } @@ -423,10 +485,10 @@ struct Rect2i { size(p_r2.size) { } Rect2i(int p_x, int p_y, int p_width, int p_height) : - position(Point2(p_x, p_y)), - size(Size2(p_width, p_height)) { + position(Point2i(p_x, p_y)), + size(Size2i(p_width, p_height)) { } - Rect2i(const Point2 &p_pos, const Size2 &p_size) : + Rect2i(const Point2i &p_pos, const Size2i &p_size) : position(p_pos), size(p_size) { } diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 182c475800..d2b626a942 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -1357,7 +1357,7 @@ void register_variant_methods() { _VariantCall::construct_funcs = memnew_arr(_VariantCall::ConstructFunc, Variant::VARIANT_MAX); _VariantCall::constant_data = memnew_arr(_VariantCall::ConstantData, Variant::VARIANT_MAX); - /* STRING */ + /* String */ bind_method(String, casecmp_to, sarray("to"), varray()); bind_method(String, nocasecmp_to, sarray("to"), varray()); @@ -1405,7 +1405,7 @@ void register_variant_methods() { bind_method(String, plus_file, sarray("file"), varray()); bind_method(String, ord_at, sarray("at"), varray()); bind_method(String, dedent, sarray(), varray()); - //string needs to be immutable when binding + // FIXME: String needs to be immutable when binding //bind_method(String, erase, sarray("position", "chars"), varray()); bind_method(String, hash, sarray(), varray()); bind_method(String, md5_text, sarray(), varray()); @@ -1415,7 +1415,7 @@ void register_variant_methods() { bind_method(String, sha1_buffer, sarray(), varray()); bind_method(String, sha256_buffer, sarray(), varray()); bind_method(String, empty, sarray(), varray()); - //static function, not sure how to bind + // FIXME: Static function, not sure how to bind //bind_method(String, humanize_size, sarray("size"), varray()); bind_method(String, is_abs_path, sarray(), varray()); @@ -1457,7 +1457,7 @@ void register_variant_methods() { bind_method(String, to_utf16_buffer, sarray(), varray()); bind_method(String, to_utf32_buffer, sarray(), varray()); - /* VECTOR2 */ + /* Vector2 */ bind_method(Vector2, angle, sarray(), varray()); bind_method(Vector2, angle_to, sarray("to"), varray()); @@ -1490,15 +1490,16 @@ void register_variant_methods() { bind_method(Vector2, cross, sarray("with"), varray()); bind_method(Vector2, abs, sarray(), varray()); bind_method(Vector2, sign, sarray(), varray()); + bind_method(Vector2, snapped, sarray("by"), varray()); bind_method(Vector2, clamped, sarray("length"), varray()); - /* VECTOR2I */ + /* Vector2i */ bind_method(Vector2i, aspect, sarray(), varray()); bind_method(Vector2i, sign, sarray(), varray()); bind_method(Vector2i, abs, sarray(), varray()); - /* RECT2 */ + /* Rect2 */ bind_method(Rect2, get_area, sarray(), varray()); bind_method(Rect2, has_no_area, sarray(), varray()); @@ -1585,7 +1586,7 @@ void register_variant_methods() { bind_methodv(intersects_ray, &Plane::intersects_ray_bind, sarray("from", "dir"), varray()); bind_methodv(intersects_segment, &Plane::intersects_segment_bind, sarray("from", "to"), varray()); - /* Quaternion */ + /* Quat */ bind_method(Quat, length, sarray(), varray()); bind_method(Quat, length_squared, sarray(), varray()); @@ -1594,13 +1595,12 @@ void register_variant_methods() { bind_method(Quat, is_equal_approx, sarray("to"), varray()); bind_method(Quat, inverse, sarray(), varray()); bind_method(Quat, dot, sarray("with"), varray()); - bind_method(Quat, xform, sarray("v3"), varray()); bind_method(Quat, slerp, sarray("b", "t"), varray()); bind_method(Quat, slerpni, sarray("b", "t"), varray()); bind_method(Quat, cubic_slerp, sarray("b", "pre_a", "post_b", "t"), varray()); bind_method(Quat, get_euler, sarray(), varray()); - //Quat is atomic, this should be done via construcror + // FIXME: Quat is atomic, this should be done via construcror //ADDFUNC1(QUAT, NIL, Quat, set_euler, VECTOR3, "euler", varray()); //ADDFUNC2(QUAT, NIL, Quat, set_axis_angle, VECTOR3, "axis", FLOAT, "angle", varray()); @@ -1620,7 +1620,7 @@ void register_variant_methods() { bind_method(Color, to_html, sarray("with_alpha"), varray(true)); bind_method(Color, blend, sarray("over"), varray()); - //Color is immutable, need to probably find a way to do this via constructor + // FIXME: Color is immutable, need to probably find a way to do this via constructor //ADDFUNC4R(COLOR, COLOR, Color, from_hsv, FLOAT, "h", FLOAT, "s", FLOAT, "v", FLOAT, "a", varray(1.0)); bind_method(Color, is_equal_approx, sarray("to"), varray()); @@ -1650,8 +1650,6 @@ void register_variant_methods() { bind_method(Callable, hash, sarray(), varray()); bind_method(Callable, unbind, sarray("argcount"), varray()); - //#define bind_custom(m_type, m_name, m_method, m_flags, m_arg_types, m_ret_type, m_arg_names) _VariantCall::_bind_custom(m_type, m_name, m_method, m_flags, m_arg_types, m_ret_type) - bind_custom(Variant::CALLABLE, "call", _VariantCall::func_Callable_call, Variant::InternalMethod::FLAG_VARARGS | Variant::InternalMethod::FLAG_RETURNS_VARIANT, Vector<Variant::Type>(), Variant::NIL, sarray()); bind_custom(Variant::CALLABLE, "call_deferred", _VariantCall::func_Callable_call_deferred, Variant::InternalMethod::FLAG_VARARGS, Vector<Variant::Type>(), Variant::NIL, sarray()); bind_custom(Variant::CALLABLE, "bind", _VariantCall::func_Callable_bind, Variant::InternalMethod::FLAG_VARARGS, Vector<Variant::Type>(), Variant::CALLABLE, sarray()); @@ -1681,9 +1679,6 @@ void register_variant_methods() { bind_method(Transform2D, rotated, sarray("phi"), varray()); bind_method(Transform2D, scaled, sarray("scale"), varray()); bind_method(Transform2D, translated, sarray("offset"), varray()); - //too complex to bind this, operator * should be used instead - //ADDFUNC1R(TRANSFORM2D, NIL, Transform2D, xform, NIL, "v", varray()); - //ADDFUNC1R(TRANSFORM2D, NIL, Transform2D, xform_inv, NIL, "v", varray()); bind_method(Transform2D, basis_xform, sarray("v"), varray()); bind_method(Transform2D, basis_xform_inv, sarray("v"), varray()); bind_method(Transform2D, interpolate_with, sarray("xform", "t"), varray()); @@ -1702,9 +1697,6 @@ void register_variant_methods() { bind_method(Basis, tdotx, sarray("with"), varray()); bind_method(Basis, tdoty, sarray("with"), varray()); bind_method(Basis, tdotz, sarray("with"), varray()); - //use the operators instead - //ADDFUNC1R(BASIS, VECTOR3, Basis, xform, VECTOR3, "v", varray()); - //ADDFUNC1R(BASIS, VECTOR3, Basis, xform_inv, VECTOR3, "v", varray()); bind_method(Basis, get_orthogonal_index, sarray(), varray()); bind_method(Basis, slerp, sarray("b", "t"), varray()); bind_method(Basis, is_equal_approx, sarray("b"), varray()); @@ -1747,9 +1739,6 @@ void register_variant_methods() { bind_method(Transform, looking_at, sarray("target", "up"), varray()); bind_method(Transform, interpolate_with, sarray("xform", "weight"), varray()); bind_method(Transform, is_equal_approx, sarray("xform"), varray()); - //use the operators instead - //ADDFUNC1R(TRANSFORM, NIL, Transform, xform, NIL, "v", varray()); - //ADDFUNC1R(TRANSFORM, NIL, Transform, xform_inv, NIL, "v", varray()); /* Dictionary */ @@ -1922,6 +1911,7 @@ void register_variant_methods() { bind_method(PackedVector2Array, invert, sarray(), varray()); bind_method(PackedVector2Array, subarray, sarray("from", "to"), varray()); bind_method(PackedVector2Array, to_byte_array, sarray(), varray()); + bind_method(PackedVector2Array, sort, sarray(), varray()); /* Vector3 Array */ @@ -1938,6 +1928,7 @@ void register_variant_methods() { bind_method(PackedVector3Array, invert, sarray(), varray()); bind_method(PackedVector3Array, subarray, sarray("from", "to"), varray()); bind_method(PackedVector3Array, to_byte_array, sarray(), varray()); + bind_method(PackedVector3Array, sort, sarray(), varray()); /* Color Array */ @@ -1954,8 +1945,9 @@ void register_variant_methods() { bind_method(PackedColorArray, invert, sarray(), varray()); bind_method(PackedColorArray, subarray, sarray("from", "to"), varray()); bind_method(PackedColorArray, to_byte_array, sarray(), varray()); + bind_method(PackedColorArray, sort, sarray(), varray()); - /* REGISTER CONSTRUCTORS */ + /* Register constructors */ _VariantCall::add_constructor(_VariantCall::Vector2_init1, Variant::VECTOR2, "x", Variant::FLOAT, "y", Variant::FLOAT); _VariantCall::add_constructor(_VariantCall::Vector2i_init1, Variant::VECTOR2I, "x", Variant::INT, "y", Variant::INT); @@ -1963,7 +1955,7 @@ void register_variant_methods() { _VariantCall::add_constructor(_VariantCall::Rect2_init1, Variant::RECT2, "position", Variant::VECTOR2, "size", Variant::VECTOR2); _VariantCall::add_constructor(_VariantCall::Rect2_init2, Variant::RECT2, "x", Variant::FLOAT, "y", Variant::FLOAT, "width", Variant::FLOAT, "height", Variant::FLOAT); - _VariantCall::add_constructor(_VariantCall::Rect2i_init1, Variant::RECT2I, "position", Variant::VECTOR2, "size", Variant::VECTOR2); + _VariantCall::add_constructor(_VariantCall::Rect2i_init1, Variant::RECT2I, "position", Variant::VECTOR2I, "size", Variant::VECTOR2I); _VariantCall::add_constructor(_VariantCall::Rect2i_init2, Variant::RECT2I, "x", Variant::INT, "y", Variant::INT, "width", Variant::INT, "height", Variant::INT); _VariantCall::add_constructor(_VariantCall::Transform2D_init2, Variant::TRANSFORM2D, "rotation", Variant::FLOAT, "position", Variant::VECTOR2); @@ -1996,7 +1988,7 @@ void register_variant_methods() { _VariantCall::add_constructor(_VariantCall::Callable_init2, Variant::CALLABLE, "object", Variant::OBJECT, "method_name", Variant::STRING_NAME); _VariantCall::add_constructor(_VariantCall::Signal_init2, Variant::SIGNAL, "object", Variant::OBJECT, "signal_name", Variant::STRING_NAME); - /* REGISTER CONSTANTS */ + /* Register constants */ _populate_named_colors(); for (Map<String, Color>::Element *color = _named_colors.front(); color; color = color->next()) { diff --git a/doc/classes/AABB.xml b/doc/classes/AABB.xml index c547563a6e..4f95b44f83 100644 --- a/doc/classes/AABB.xml +++ b/doc/classes/AABB.xml @@ -176,8 +176,18 @@ Returns [code]true[/code] if the [AABB] is on both sides of a plane. </description> </method> + <method name="intersects_ray"> + <return type="Variant"> + </return> + <argument index="0" name="from" type="Vector3"> + </argument> + <argument index="1" name="dir" type="Vector3"> + </argument> + <description> + </description> + </method> <method name="intersects_segment"> - <return type="bool"> + <return type="Variant"> </return> <argument index="0" name="from" type="Vector3"> </argument> diff --git a/doc/classes/AnimatedSprite2D.xml b/doc/classes/AnimatedSprite2D.xml index 39228eab79..969e9cc85b 100644 --- a/doc/classes/AnimatedSprite2D.xml +++ b/doc/classes/AnimatedSprite2D.xml @@ -63,12 +63,6 @@ <member name="playing" type="bool" setter="_set_playing" getter="_is_playing" default="false"> If [code]true[/code], the [member animation] is currently playing. </member> - <member name="shininess" type="float" setter="set_shininess" getter="get_shininess" default="1.0"> - Strength of the specular light effect of this [AnimatedSprite2D]. - </member> - <member name="specular_color" type="Color" setter="set_specular_color" getter="get_specular_color" default="Color( 1, 1, 1, 1 )"> - The color of the specular light effect. - </member> <member name="speed_scale" type="float" setter="set_speed_scale" getter="get_speed_scale" default="1.0"> The animation speed is multiplied by this value. </member> diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml index 87b7443a8a..d0f90f513d 100644 --- a/doc/classes/Array.xml +++ b/doc/classes/Array.xml @@ -160,7 +160,7 @@ </argument> <argument index="1" name="obj" type="Object"> </argument> - <argument index="2" name="func" type="String"> + <argument index="2" name="func" type="StringName"> </argument> <argument index="3" name="before" type="bool" default="true"> </argument> @@ -362,7 +362,7 @@ </description> </method> <method name="resize"> - <return type="void"> + <return type="int"> </return> <argument index="0" name="size" type="int"> </argument> @@ -433,7 +433,7 @@ </return> <argument index="0" name="obj" type="Object"> </argument> - <argument index="1" name="func" type="String"> + <argument index="1" name="func" type="StringName"> </argument> <description> Sorts the array using a custom method. The arguments are an object that holds the method and the name of such method. The custom method receives two arguments (a pair of elements from the array) and must return either [code]true[/code] or [code]false[/code]. diff --git a/doc/classes/Basis.xml b/doc/classes/Basis.xml index 42ca3ad24b..4201a31402 100644 --- a/doc/classes/Basis.xml +++ b/doc/classes/Basis.xml @@ -187,25 +187,6 @@ Returns the transposed version of the matrix. </description> </method> - <method name="xform"> - <return type="Vector3"> - </return> - <argument index="0" name="v" type="Vector3"> - </argument> - <description> - Returns a vector transformed (multiplied) by the matrix. - </description> - </method> - <method name="xform_inv"> - <return type="Vector3"> - </return> - <argument index="0" name="v" type="Vector3"> - </argument> - <description> - Returns a vector transformed (multiplied) by the transposed basis matrix. - [b]Note:[/b] This results in a multiplication by the inverse of the matrix only if it represents a rotation-reflection. - </description> - </method> </methods> <members> <member name="x" type="Vector3" setter="" getter="" default="Vector3( 1, 0, 0 )"> diff --git a/doc/classes/CPUParticles2D.xml b/doc/classes/CPUParticles2D.xml index 7244da56ca..fcf2feb3b9 100644 --- a/doc/classes/CPUParticles2D.xml +++ b/doc/classes/CPUParticles2D.xml @@ -238,10 +238,6 @@ <member name="local_coords" type="bool" setter="set_use_local_coordinates" getter="get_use_local_coordinates" default="true"> If [code]true[/code], particles use the parent node's coordinate space. If [code]false[/code], they use global coordinates. </member> - <member name="normalmap" type="Texture2D" setter="set_normalmap" getter="get_normalmap"> - Normal map to be used for the [member texture] property. - [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines. - </member> <member name="one_shot" type="bool" setter="set_one_shot" getter="get_one_shot" default="false"> If [code]true[/code], only one emission cycle occurs. If set [code]true[/code] during a cycle, emission will stop at the cycle's end. </member> diff --git a/doc/classes/Callable.xml b/doc/classes/Callable.xml index ad5c549fee..7aaf087540 100644 --- a/doc/classes/Callable.xml +++ b/doc/classes/Callable.xml @@ -48,7 +48,7 @@ </description> </method> <method name="bind" qualifiers="vararg"> - <return type="void"> + <return type="Callable"> </return> <description> </description> diff --git a/doc/classes/CanvasGroup.xml b/doc/classes/CanvasGroup.xml new file mode 100644 index 0000000000..ceeda6c3f5 --- /dev/null +++ b/doc/classes/CanvasGroup.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="CanvasGroup" inherits="Node2D" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="clear_margin" type="float" setter="set_clear_margin" getter="get_clear_margin" default="10.0"> + </member> + <member name="fit_margin" type="float" setter="set_fit_margin" getter="get_fit_margin" default="10.0"> + </member> + <member name="use_mipmaps" type="bool" setter="set_use_mipmaps" getter="is_using_mipmaps" default="false"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml index 9f6baae8a3..8efa1adae8 100644 --- a/doc/classes/CanvasItem.xml +++ b/doc/classes/CanvasItem.xml @@ -86,16 +86,6 @@ </argument> <argument index="3" name="texture" type="Texture2D" default="null"> </argument> - <argument index="4" name="normal_map" type="Texture2D" default="null"> - </argument> - <argument index="5" name="specular_map" type="Texture2D" default="null"> - </argument> - <argument index="6" name="specular_shininess" type="Color" default="Color( 1, 1, 1, 1 )"> - </argument> - <argument index="7" name="texture_filter" type="int" enum="CanvasItem.TextureFilter" default="0"> - </argument> - <argument index="8" name="texture_repeat" type="int" enum="CanvasItem.TextureRepeat" default="0"> - </argument> <description> Draws a colored polygon of any amount of points, convex or concave. </description> @@ -122,19 +112,9 @@ </argument> <argument index="1" name="texture" type="Texture2D"> </argument> - <argument index="2" name="normal_map" type="Texture2D" default="null"> - </argument> - <argument index="3" name="specular_map" type="Texture2D" default="null"> + <argument index="2" name="transform" type="Transform2D" default="Transform2D( 1, 0, 0, 1, 0, 0 )"> </argument> - <argument index="4" name="specular_shininess" type="Color" default="Color( 1, 1, 1, 1 )"> - </argument> - <argument index="5" name="transform" type="Transform2D" default="Transform2D( 1, 0, 0, 1, 0, 0 )"> - </argument> - <argument index="6" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )"> - </argument> - <argument index="7" name="texture_filter" type="int" enum="CanvasItem.TextureFilter" default="0"> - </argument> - <argument index="8" name="texture_repeat" type="int" enum="CanvasItem.TextureRepeat" default="0"> + <argument index="3" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )"> </argument> <description> Draws a [Mesh] in 2D, using the provided texture. See [MeshInstance2D] for related documentation. @@ -173,16 +153,6 @@ </argument> <argument index="1" name="texture" type="Texture2D"> </argument> - <argument index="2" name="normal_map" type="Texture2D" default="null"> - </argument> - <argument index="3" name="specular_map" type="Texture2D" default="null"> - </argument> - <argument index="4" name="specular_shininess" type="Color" default="Color( 1, 1, 1, 1 )"> - </argument> - <argument index="5" name="texture_filter" type="int" enum="CanvasItem.TextureFilter" default="0"> - </argument> - <argument index="6" name="texture_repeat" type="int" enum="CanvasItem.TextureRepeat" default="0"> - </argument> <description> Draws a [MultiMesh] in 2D with the provided texture. See [MultiMeshInstance2D] for related documentation. </description> @@ -198,16 +168,6 @@ </argument> <argument index="3" name="texture" type="Texture2D" default="null"> </argument> - <argument index="4" name="normal_map" type="Texture2D" default="null"> - </argument> - <argument index="5" name="specular_map" type="Texture2D" default="null"> - </argument> - <argument index="6" name="specular_shininess" type="Color" default="Color( 1, 1, 1, 1 )"> - </argument> - <argument index="7" name="texture_filter" type="int" enum="CanvasItem.TextureFilter" default="0"> - </argument> - <argument index="8" name="texture_repeat" type="int" enum="CanvasItem.TextureRepeat" default="0"> - </argument> <description> Draws a polygon of any amount of points, convex or concave. </description> @@ -251,16 +211,6 @@ </argument> <argument index="4" name="width" type="float" default="1.0"> </argument> - <argument index="5" name="normal_map" type="Texture2D" default="null"> - </argument> - <argument index="6" name="specular_map" type="Texture2D" default="null"> - </argument> - <argument index="7" name="specular_shininess" type="Color" default="Color( 1, 1, 1, 1 )"> - </argument> - <argument index="8" name="texture_filter" type="int" enum="CanvasItem.TextureFilter" default="0"> - </argument> - <argument index="9" name="texture_repeat" type="int" enum="CanvasItem.TextureRepeat" default="0"> - </argument> <description> Draws a custom primitive. 1 point for a point, 2 points for a line, 3 points for a triangle, and 4 points for a quad. </description> @@ -358,16 +308,6 @@ </argument> <argument index="2" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )"> </argument> - <argument index="3" name="normal_map" type="Texture2D" default="null"> - </argument> - <argument index="4" name="specular_map" type="Texture2D" default="null"> - </argument> - <argument index="5" name="specular_shininess" type="Color" default="Color( 1, 1, 1, 1 )"> - </argument> - <argument index="6" name="texture_filter" type="int" enum="CanvasItem.TextureFilter" default="0"> - </argument> - <argument index="7" name="texture_repeat" type="int" enum="CanvasItem.TextureRepeat" default="0"> - </argument> <description> Draws a texture at a given position. </description> @@ -385,16 +325,6 @@ </argument> <argument index="4" name="transpose" type="bool" default="false"> </argument> - <argument index="5" name="normal_map" type="Texture2D" default="null"> - </argument> - <argument index="6" name="specular_map" type="Texture2D" default="null"> - </argument> - <argument index="7" name="specular_shininess" type="Color" default="Color( 1, 1, 1, 1 )"> - </argument> - <argument index="8" name="texture_filter" type="int" enum="CanvasItem.TextureFilter" default="0"> - </argument> - <argument index="9" name="texture_repeat" type="int" enum="CanvasItem.TextureRepeat" default="0"> - </argument> <description> Draws a textured rectangle at a given position, optionally modulated by a color. If [code]transpose[/code] is [code]true[/code], the texture will have its X and Y coordinates swapped. </description> @@ -412,17 +342,7 @@ </argument> <argument index="4" name="transpose" type="bool" default="false"> </argument> - <argument index="5" name="normal_map" type="Texture2D" default="null"> - </argument> - <argument index="6" name="specular_map" type="Texture2D" default="null"> - </argument> - <argument index="7" name="specular_shininess" type="Color" default="Color( 1, 1, 1, 1 )"> - </argument> - <argument index="8" name="clip_uv" type="bool" default="true"> - </argument> - <argument index="9" name="texture_filter" type="int" enum="CanvasItem.TextureFilter" default="0"> - </argument> - <argument index="10" name="texture_repeat" type="int" enum="CanvasItem.TextureRepeat" default="0"> + <argument index="5" name="clip_uv" type="bool" default="true"> </argument> <description> Draws a textured rectangle region at a given position, optionally modulated by a color. If [code]transpose[/code] is [code]true[/code], the texture will have its X and Y coordinates swapped. @@ -592,6 +512,8 @@ </method> </methods> <members> + <member name="clip_children" type="bool" setter="set_clip_children" getter="is_clipping_children" default="false"> + </member> <member name="light_mask" type="int" setter="set_light_mask" getter="get_light_mask" default="1"> The rendering layers in which this [CanvasItem] responds to [Light2D] nodes. </member> diff --git a/doc/classes/CanvasTexture.xml b/doc/classes/CanvasTexture.xml new file mode 100644 index 0000000000..0ca132746b --- /dev/null +++ b/doc/classes/CanvasTexture.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="CanvasTexture" inherits="Texture2D" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="diffuse_texture" type="Texture2D" setter="set_diffuse_texture" getter="get_diffuse_texture"> + </member> + <member name="normal_texture" type="Texture2D" setter="set_normal_texture" getter="get_normal_texture"> + </member> + <member name="specular_color" type="Color" setter="set_specular_color" getter="get_specular_color" default="Color( 1, 1, 1, 1 )"> + </member> + <member name="specular_shininess" type="float" setter="set_specular_shininess" getter="get_specular_shininess" default="1.0"> + </member> + <member name="specular_texture" type="Texture2D" setter="set_specular_texture" getter="get_specular_texture"> + </member> + <member name="texture_filter" type="int" setter="set_texture_filter" getter="get_texture_filter" enum="CanvasItem.TextureFilter" default="0"> + </member> + <member name="texture_repeat" type="int" setter="set_texture_repeat" getter="get_texture_repeat" enum="CanvasItem.TextureRepeat" default="0"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/Color.xml b/doc/classes/Color.xml index 70529e0ee6..ca52d27a52 100644 --- a/doc/classes/Color.xml +++ b/doc/classes/Color.xml @@ -178,29 +178,6 @@ [/codeblocks] </description> </method> - <method name="from_hsv"> - <return type="Color"> - </return> - <argument index="0" name="h" type="float"> - </argument> - <argument index="1" name="s" type="float"> - </argument> - <argument index="2" name="v" type="float"> - </argument> - <argument index="3" name="a" type="float" default="1.0"> - </argument> - <description> - Constructs a color from an HSV profile. [code]h[/code], [code]s[/code], and [code]v[/code] are values between 0 and 1. - [codeblocks] - [gdscript] - var color = Color.from_hsv(0.58, 0.5, 0.79, 0.8) # Equivalent to HSV(210, 50, 79, 0.8) or Color8(100, 151, 201, 0.8) - [/gdscript] - [csharp] - Color color = Color.FromHsv(0.58f, 0.5f, 0.79f, 0.8f); // Equivalent to HSV(210, 50, 79, 0.8) or Color8(100, 151, 201, 0.8) - [/csharp] - [/codeblocks] - </description> - </method> <method name="inverted"> <return type="Color"> </return> @@ -221,7 +198,7 @@ <method name="is_equal_approx"> <return type="bool"> </return> - <argument index="0" name="color" type="Color"> + <argument index="0" name="to" type="Color"> </argument> <description> Returns [code]true[/code] if this color and [code]color[/code] are approximately equal, by running [method @GDScript.is_equal_approx] on each component. diff --git a/doc/classes/ColorRect.xml b/doc/classes/ColorRect.xml index 7c0cd981e4..09ba4c8b26 100644 --- a/doc/classes/ColorRect.xml +++ b/doc/classes/ColorRect.xml @@ -12,7 +12,7 @@ <methods> </methods> <members> - <member name="color" type="Color" setter="set_frame_color" getter="get_frame_color" default="Color( 1, 1, 1, 1 )"> + <member name="color" type="Color" setter="set_color" getter="get_color" default="Color( 1, 1, 1, 1 )"> The fill color. [codeblocks] [gdscript] diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index f495bfe894..6ea7b79dff 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -75,15 +75,17 @@ </description> </method> <method name="_make_custom_tooltip" qualifiers="virtual"> - <return type="Object"> + <return type="Control"> </return> <argument index="0" name="for_text" type="String"> </argument> <description> - Virtual method to be implemented by the user. Returns a [Control] node that should be used as a tooltip instead of the default one. Use [code]for_text[/code] parameter to determine what text the tooltip should contain (likely the contents of [member hint_tooltip]). - The returned node must be of type [Control] or Control-derieved. It can have child nodes of any type. It is freed when the tooltip disappears, so make sure you always provide a new instance, not e.g. a node from scene. When [code]null[/code] or non-Control node is returned, the default tooltip will be used instead. + Virtual method to be implemented by the user. Returns a [Control] node that should be used as a tooltip instead of the default one. The [code]for_text[/code] includes the contents of the [member hint_tooltip] property. + The returned node must be of type [Control] or Control-derived. It can have child nodes of any type. It is freed when the tooltip disappears, so make sure you always provide a new instance (if you want to use a pre-existing node from your scene tree, you can duplicate it and pass the duplicated instance).When [code]null[/code] or a non-Control node is returned, the default tooltip will be used instead. + The returned node will be added as child to a [PopupPanel], so you should only provide the contents of that panel. That [PopupPanel] can be themed using [method Theme.set_stylebox] for the type [code]"TooltipPanel"[/code] (see [member hint_tooltip] for an example). [b]Note:[/b] The tooltip is shrunk to minimal size. If you want to ensure it's fully visible, you might want to set its [member rect_min_size] to some non-zero value. - Example of usage with custom-constructed node: + [b]Note:[/b] The node (and any relevant children) should be [member CanvasItem.visible] when returned, otherwise the viewport that instantiates it will not be able to calculate its minimum size reliably. + Example of usage with a custom-constructed node: [codeblocks] [gdscript] func _make_custom_tooltip(for_text): @@ -92,7 +94,7 @@ return label [/gdscript] [csharp] - public override Godot.Object _MakeCustomTooltip(String forText) + public override Godot.Control _MakeCustomTooltip(String forText) { var label = new Label(); label.Text = forText; @@ -100,18 +102,18 @@ } [/csharp] [/codeblocks] - Example of usage with custom scene instance: + Example of usage with a custom scene instance: [codeblocks] [gdscript] func _make_custom_tooltip(for_text): - var tooltip = preload("SomeTooltipScene.tscn").instance() + var tooltip = preload("res://SomeTooltipScene.tscn").instance() tooltip.get_node("Label").text = for_text return tooltip [/gdscript] [csharp] - public override Godot.Object _MakeCustomTooltip(String forText) + public override Godot.Control _MakeCustomTooltip(String forText) { - Node tooltip = ResourceLoader.Load<PackedScene>("SomeTooltipScene.tscn").Instance(); + Node tooltip = ResourceLoader.Load<PackedScene>("res://SomeTooltipScene.tscn").Instance(); tooltip.GetNode<Label>("Label").Text = forText; return tooltip; } @@ -993,6 +995,25 @@ </member> <member name="hint_tooltip" type="String" setter="set_tooltip" getter="_get_tooltip" default=""""> Changes the tooltip text. The tooltip appears when the user's mouse cursor stays idle over this control for a few moments, provided that the [member mouse_filter] property is not [constant MOUSE_FILTER_IGNORE]. You can change the time required for the tooltip to appear with [code]gui/timers/tooltip_delay_sec[/code] option in Project Settings. + The tooltip popup will use either a default implementation, or a custom one that you can provide by overriding [method _make_custom_tooltip]. The default tooltip includes a [PopupPanel] and [Label] whose theme properties can be customized using [Theme] methods with the [code]"TooltipPanel"[/code] and [code]"TooltipLabel"[/code] respectively. For example: + [codeblocks] + [gdscript] + var style_box = StyleBoxFlat.new() + style_box.set_bg_color(Color(1, 1, 0)) + style_box.set_border_width_all(2) + # We assume here that the `theme` property has been assigned a custom Theme beforehand. + theme.set_stylebox("panel", "TooltipPanel", style_box) + theme.set_color("font_color", "TooltipLabel", Color(0, 1, 1)) + [/gdscript] + [csharp] + var styleBox = new StyleBoxFlat(); + styleBox.SetBgColor(new Color(1, 1, 0)); + styleBox.SetBorderWidthAll(2); + // We assume here that the `Theme` property has been assigned a custom Theme beforehand. + Theme.SetStyleBox("panel", "TooltipPanel", styleBox); + Theme.SetColor("font_color", "TooltipLabel", new Color(0, 1, 1)); + [/csharp] + [/codeblocks] </member> <member name="margin_bottom" type="float" setter="set_margin" getter="get_margin" default="0.0"> Distance between the node's bottom edge and its parent control, based on [member anchor_bottom]. diff --git a/doc/classes/DirectionalLight2D.xml b/doc/classes/DirectionalLight2D.xml new file mode 100644 index 0000000000..a6eb780159 --- /dev/null +++ b/doc/classes/DirectionalLight2D.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="DirectionalLight2D" inherits="Light2D" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="height" type="float" setter="set_height" getter="get_height" default="0.0"> + The height of the light. Used with 2D normal mapping. + </member> + <member name="max_distance" type="float" setter="set_max_distance" getter="get_max_distance" default="10000.0"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml index 6a64a7aa55..95d88e86a6 100644 --- a/doc/classes/EditorPlugin.xml +++ b/doc/classes/EditorPlugin.xml @@ -379,7 +379,7 @@ Remember that you have to manage the visibility of all your editor controls manually. </description> </method> - <method name="queue_save_layout" qualifiers="const"> + <method name="queue_save_layout"> <return type="void"> </return> <description> diff --git a/doc/classes/GPUParticles2D.xml b/doc/classes/GPUParticles2D.xml index ba201af5db..c09151405a 100644 --- a/doc/classes/GPUParticles2D.xml +++ b/doc/classes/GPUParticles2D.xml @@ -52,10 +52,6 @@ <member name="local_coords" type="bool" setter="set_use_local_coordinates" getter="get_use_local_coordinates" default="true"> If [code]true[/code], particles use the parent node's coordinate space. If [code]false[/code], they use global coordinates. </member> - <member name="normal_map" type="Texture2D" setter="set_normal_map" getter="get_normal_map"> - Normal map to be used for the [member texture] property. - [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines. - </member> <member name="one_shot" type="bool" setter="set_one_shot" getter="get_one_shot" default="false"> If [code]true[/code], only one emission cycle occurs. If set [code]true[/code] during a cycle, emission will stop at the cycle's end. </member> diff --git a/doc/classes/Geometry2D.xml b/doc/classes/Geometry2D.xml index 86dc8e864a..a6bcc1301b 100644 --- a/doc/classes/Geometry2D.xml +++ b/doc/classes/Geometry2D.xml @@ -200,11 +200,11 @@ Inflates or deflates [code]polygon[/code] by [code]delta[/code] units (pixels). If [code]delta[/code] is positive, makes the polygon grow outward. If [code]delta[/code] is negative, shrinks the polygon inward. Returns an array of polygons because inflating/deflating may result in multiple discrete polygons. Returns an empty array if [code]delta[/code] is negative and the absolute value of it approximately exceeds the minimum bounding rectangle dimensions of the polygon. Each polygon's vertices will be rounded as determined by [code]join_type[/code], see [enum PolyJoinType]. The operation may result in an outer polygon (boundary) and inner polygon (hole) produced which could be distinguished by calling [method is_polygon_clockwise]. - [b]Note:[/b] To translate the polygon's vertices specifically, use the [method Transform2D.xform] method: + [b]Note:[/b] To translate the polygon's vertices specifically, multiply them to a [Transform2D]: [codeblock] var polygon = PackedVector2Array([Vector2(0, 0), Vector2(100, 0), Vector2(100, 100), Vector2(0, 100)]) var offset = Vector2(50, 50) - polygon = Transform2D(0, offset).xform(polygon) + polygon = Transform2D(0, offset) * polygon print(polygon) # prints [Vector2(50, 50), Vector2(150, 50), Vector2(150, 150), Vector2(50, 150)] [/codeblock] </description> diff --git a/doc/classes/Light2D.xml b/doc/classes/Light2D.xml index c5f0c2df8c..f6698352ab 100644 --- a/doc/classes/Light2D.xml +++ b/doc/classes/Light2D.xml @@ -11,8 +11,25 @@ <link title="2D lights and shadows">https://docs.godotengine.org/en/latest/tutorials/2d/2d_lights_and_shadows.html</link> </tutorials> <methods> + <method name="get_height" qualifiers="const"> + <return type="float"> + </return> + <description> + </description> + </method> + <method name="set_height"> + <return type="void"> + </return> + <argument index="0" name="height" type="float"> + </argument> + <description> + </description> + </method> </methods> <members> + <member name="blend_mode" type="int" setter="set_blend_mode" getter="get_blend_mode" enum="Light2D.BlendMode" default="0"> + The Light2D's blend mode. See [enum BlendMode] constants for values. + </member> <member name="color" type="Color" setter="set_color" getter="get_color" default="Color( 1, 1, 1, 1 )"> The Light2D's [Color]. </member> @@ -25,15 +42,6 @@ <member name="energy" type="float" setter="set_energy" getter="get_energy" default="1.0"> The Light2D's energy value. The larger the value, the stronger the light. </member> - <member name="mode" type="int" setter="set_mode" getter="get_mode" enum="Light2D.Mode" default="0"> - The Light2D's mode. See [enum Mode] constants for values. - </member> - <member name="offset" type="Vector2" setter="set_texture_offset" getter="get_texture_offset" default="Vector2( 0, 0 )"> - The offset of the Light2D's [code]texture[/code]. - </member> - <member name="range_height" type="float" setter="set_height" getter="get_height" default="0.0"> - The height of the Light2D. Used with 2D normal mapping. - </member> <member name="range_item_cull_mask" type="int" setter="set_item_cull_mask" getter="get_item_cull_mask" default="1"> The layer mask. Only objects with a matching mask will be affected by the Light2D. </member> @@ -49,9 +57,6 @@ <member name="range_z_min" type="int" setter="set_z_range_min" getter="get_z_range_min" default="-1024"> Minimum [code]z[/code] value of objects that are affected by the Light2D. </member> - <member name="shadow_buffer_size" type="int" setter="set_shadow_buffer_size" getter="get_shadow_buffer_size" default="2048"> - Shadow buffer size. - </member> <member name="shadow_color" type="Color" setter="set_shadow_color" getter="get_shadow_color" default="Color( 0, 0, 0, 0 )"> [Color] of shadows cast by the Light2D. </member> @@ -67,26 +72,8 @@ <member name="shadow_item_cull_mask" type="int" setter="set_item_shadow_cull_mask" getter="get_item_shadow_cull_mask" default="1"> The shadow mask. Used with [LightOccluder2D] to cast shadows. Only occluders with a matching light mask will cast shadows. </member> - <member name="texture" type="Texture2D" setter="set_texture" getter="get_texture"> - [Texture2D] used for the Light2D's appearance. - </member> - <member name="texture_scale" type="float" setter="set_texture_scale" getter="get_texture_scale" default="1.0"> - The [code]texture[/code]'s scale factor. - </member> </members> <constants> - <constant name="MODE_ADD" value="0" enum="Mode"> - Adds the value of pixels corresponding to the Light2D to the values of pixels under it. This is the common behavior of a light. - </constant> - <constant name="MODE_SUB" value="1" enum="Mode"> - Subtracts the value of pixels corresponding to the Light2D to the values of pixels under it, resulting in inversed light effect. - </constant> - <constant name="MODE_MIX" value="2" enum="Mode"> - Mix the value of pixels corresponding to the Light2D to the values of pixels under it by linear interpolation. - </constant> - <constant name="MODE_MASK" value="3" enum="Mode"> - The light texture of the Light2D is used as a mask, hiding or revealing parts of the screen underneath depending on the value of each pixel of the light (mask) texture. - </constant> <constant name="SHADOW_FILTER_NONE" value="0" enum="ShadowFilter"> No filter applies to the shadow map. See [member shadow_filter]. </constant> @@ -96,5 +83,14 @@ <constant name="SHADOW_FILTER_PCF13" value="2" enum="ShadowFilter"> Percentage closer filtering (13 samples) applies to the shadow map. See [member shadow_filter]. </constant> + <constant name="BLEND_MODE_ADD" value="0" enum="BlendMode"> + Adds the value of pixels corresponding to the Light2D to the values of pixels under it. This is the common behavior of a light. + </constant> + <constant name="BLEND_MODE_SUB" value="1" enum="BlendMode"> + Subtracts the value of pixels corresponding to the Light2D to the values of pixels under it, resulting in inversed light effect. + </constant> + <constant name="BLEND_MODE_MIX" value="2" enum="BlendMode"> + Mix the value of pixels corresponding to the Light2D to the values of pixels under it by linear interpolation. + </constant> </constants> </class> diff --git a/doc/classes/LinkButton.xml b/doc/classes/LinkButton.xml index 2d475fc449..15307de897 100644 --- a/doc/classes/LinkButton.xml +++ b/doc/classes/LinkButton.xml @@ -12,7 +12,6 @@ <methods> </methods> <members> - <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" override="true" enum="Control.FocusMode" default="0" /> <member name="mouse_default_cursor_shape" type="int" setter="set_default_cursor_shape" getter="get_default_cursor_shape" override="true" enum="Control.CursorShape" default="2" /> <member name="text" type="String" setter="set_text" getter="get_text" default=""""> The button's text that will be displayed inside the button's area. diff --git a/doc/classes/MenuButton.xml b/doc/classes/MenuButton.xml index d97e0f0f21..fe38c08280 100644 --- a/doc/classes/MenuButton.xml +++ b/doc/classes/MenuButton.xml @@ -31,7 +31,6 @@ <members> <member name="action_mode" type="int" setter="set_action_mode" getter="get_action_mode" override="true" enum="BaseButton.ActionMode" default="0" /> <member name="flat" type="bool" setter="set_flat" getter="is_flat" override="true" default="true" /> - <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" override="true" enum="Control.FocusMode" default="0" /> <member name="switch_on_hover" type="bool" setter="set_switch_on_hover" getter="is_switch_on_hover" default="false"> If [code]true[/code], when the cursor hovers above another [MenuButton] within the same parent which also has [code]switch_on_hover[/code] enabled, it will close the current [MenuButton] and open the other one. </member> diff --git a/doc/classes/NodePath.xml b/doc/classes/NodePath.xml index 658f0e6c28..f711ba4d6b 100644 --- a/doc/classes/NodePath.xml +++ b/doc/classes/NodePath.xml @@ -65,7 +65,7 @@ </description> </method> <method name="get_concatenated_subnames"> - <return type="String"> + <return type="StringName"> </return> <description> Returns all subnames concatenated with a colon character ([code]:[/code]) as separator, i.e. the right side of the first colon in a node path. @@ -76,7 +76,7 @@ </description> </method> <method name="get_name"> - <return type="String"> + <return type="StringName"> </return> <argument index="0" name="idx" type="int"> </argument> @@ -99,7 +99,7 @@ </description> </method> <method name="get_subname"> - <return type="String"> + <return type="StringName"> </return> <argument index="0" name="idx" type="int"> </argument> diff --git a/doc/classes/PackedByteArray.xml b/doc/classes/PackedByteArray.xml index 0b43522bce..7c2d566466 100644 --- a/doc/classes/PackedByteArray.xml +++ b/doc/classes/PackedByteArray.xml @@ -20,9 +20,9 @@ </description> </method> <method name="append"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="byte" type="int"> + <argument index="0" name="value" type="int"> </argument> <description> Appends an element at the end of the array (alias of [method push_back]). @@ -128,9 +128,9 @@ <method name="insert"> <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="at_index" type="int"> </argument> - <argument index="1" name="byte" type="int"> + <argument index="1" name="value" type="int"> </argument> <description> Inserts a new element at a given position in the array. The position must be valid, or at the end of the array ([code]idx == size()[/code]). @@ -144,9 +144,9 @@ </description> </method> <method name="push_back"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="byte" type="int"> + <argument index="0" name="value" type="int"> </argument> <description> Appends an element at the end of the array. @@ -155,16 +155,16 @@ <method name="remove"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> <description> Removes an element from the array by index. </description> </method> <method name="resize"> - <return type="void"> + <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="new_size" type="int"> </argument> <description> Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size. @@ -173,9 +173,9 @@ <method name="set"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> - <argument index="1" name="byte" type="int"> + <argument index="1" name="value" type="int"> </argument> <description> Changes the byte at the given index. diff --git a/doc/classes/PackedColorArray.xml b/doc/classes/PackedColorArray.xml index ec087e1b39..c42d14c5bd 100644 --- a/doc/classes/PackedColorArray.xml +++ b/doc/classes/PackedColorArray.xml @@ -20,9 +20,9 @@ </description> </method> <method name="append"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="color" type="Color"> + <argument index="0" name="value" type="Color"> </argument> <description> Appends an element at the end of the array (alias of [method push_back]). @@ -56,9 +56,9 @@ <method name="insert"> <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="at_index" type="int"> </argument> - <argument index="1" name="color" type="Color"> + <argument index="1" name="value" type="Color"> </argument> <description> Inserts a new element at a given position in the array. The position must be valid, or at the end of the array ([code]idx == size()[/code]). @@ -72,9 +72,9 @@ </description> </method> <method name="push_back"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="color" type="Color"> + <argument index="0" name="value" type="Color"> </argument> <description> Appends a value to the array. @@ -83,16 +83,16 @@ <method name="remove"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> <description> Removes an element from the array by index. </description> </method> <method name="resize"> - <return type="void"> + <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="new_size" type="int"> </argument> <description> Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size. @@ -101,9 +101,9 @@ <method name="set"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> - <argument index="1" name="color" type="Color"> + <argument index="1" name="value" type="Color"> </argument> <description> Changes the [Color] at the given index. @@ -123,6 +123,22 @@ Sorts the elements of the array in ascending order. </description> </method> + <method name="subarray"> + <return type="PackedColorArray"> + </return> + <argument index="0" name="from" type="int"> + </argument> + <argument index="1" name="to" type="int"> + </argument> + <description> + </description> + </method> + <method name="to_byte_array"> + <return type="PackedByteArray"> + </return> + <description> + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/PackedFloat32Array.xml b/doc/classes/PackedFloat32Array.xml index a6b726944b..dd84648251 100644 --- a/doc/classes/PackedFloat32Array.xml +++ b/doc/classes/PackedFloat32Array.xml @@ -21,7 +21,7 @@ </description> </method> <method name="append"> - <return type="void"> + <return type="bool"> </return> <argument index="0" name="value" type="float"> </argument> @@ -57,7 +57,7 @@ <method name="insert"> <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="at_index" type="int"> </argument> <argument index="1" name="value" type="float"> </argument> @@ -73,7 +73,7 @@ </description> </method> <method name="push_back"> - <return type="void"> + <return type="bool"> </return> <argument index="0" name="value" type="float"> </argument> @@ -84,16 +84,16 @@ <method name="remove"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> <description> Removes an element from the array by index. </description> </method> <method name="resize"> - <return type="void"> + <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="new_size" type="int"> </argument> <description> Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size. @@ -102,7 +102,7 @@ <method name="set"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> <argument index="1" name="value" type="float"> </argument> @@ -124,6 +124,22 @@ Sorts the elements of the array in ascending order. </description> </method> + <method name="subarray"> + <return type="PackedFloat32Array"> + </return> + <argument index="0" name="from" type="int"> + </argument> + <argument index="1" name="to" type="int"> + </argument> + <description> + </description> + </method> + <method name="to_byte_array"> + <return type="PackedByteArray"> + </return> + <description> + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/PackedFloat64Array.xml b/doc/classes/PackedFloat64Array.xml index f867cda3b6..91c3f4874b 100644 --- a/doc/classes/PackedFloat64Array.xml +++ b/doc/classes/PackedFloat64Array.xml @@ -21,7 +21,7 @@ </description> </method> <method name="append"> - <return type="void"> + <return type="bool"> </return> <argument index="0" name="value" type="float"> </argument> @@ -57,7 +57,7 @@ <method name="insert"> <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="at_index" type="int"> </argument> <argument index="1" name="value" type="float"> </argument> @@ -73,7 +73,7 @@ </description> </method> <method name="push_back"> - <return type="void"> + <return type="bool"> </return> <argument index="0" name="value" type="float"> </argument> @@ -84,16 +84,16 @@ <method name="remove"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> <description> Removes an element from the array by index. </description> </method> <method name="resize"> - <return type="void"> + <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="new_size" type="int"> </argument> <description> Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size. @@ -102,7 +102,7 @@ <method name="set"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> <argument index="1" name="value" type="float"> </argument> @@ -124,6 +124,22 @@ Sorts the elements of the array in ascending order. </description> </method> + <method name="subarray"> + <return type="PackedFloat64Array"> + </return> + <argument index="0" name="from" type="int"> + </argument> + <argument index="1" name="to" type="int"> + </argument> + <description> + </description> + </method> + <method name="to_byte_array"> + <return type="PackedByteArray"> + </return> + <description> + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/PackedInt32Array.xml b/doc/classes/PackedInt32Array.xml index b796d9cacb..a0a9922d0c 100644 --- a/doc/classes/PackedInt32Array.xml +++ b/doc/classes/PackedInt32Array.xml @@ -21,9 +21,9 @@ </description> </method> <method name="append"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="integer" type="int"> + <argument index="0" name="value" type="int"> </argument> <description> Appends an element at the end of the array (alias of [method push_back]). @@ -57,9 +57,9 @@ <method name="insert"> <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="at_index" type="int"> </argument> - <argument index="1" name="integer" type="int"> + <argument index="1" name="value" type="int"> </argument> <description> Inserts a new integer at a given position in the array. The position must be valid, or at the end of the array ([code]idx == size()[/code]). @@ -73,9 +73,9 @@ </description> </method> <method name="push_back"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="integer" type="int"> + <argument index="0" name="value" type="int"> </argument> <description> Appends a value to the array. @@ -84,16 +84,16 @@ <method name="remove"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> <description> Removes an element from the array by index. </description> </method> <method name="resize"> - <return type="void"> + <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="new_size" type="int"> </argument> <description> Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size. @@ -102,9 +102,9 @@ <method name="set"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> - <argument index="1" name="integer" type="int"> + <argument index="1" name="value" type="int"> </argument> <description> Changes the integer at the given index. @@ -124,6 +124,22 @@ Sorts the elements of the array in ascending order. </description> </method> + <method name="subarray"> + <return type="PackedInt32Array"> + </return> + <argument index="0" name="from" type="int"> + </argument> + <argument index="1" name="to" type="int"> + </argument> + <description> + </description> + </method> + <method name="to_byte_array"> + <return type="PackedByteArray"> + </return> + <description> + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/PackedInt64Array.xml b/doc/classes/PackedInt64Array.xml index 3d0d9a1360..542dabcfa0 100644 --- a/doc/classes/PackedInt64Array.xml +++ b/doc/classes/PackedInt64Array.xml @@ -21,9 +21,9 @@ </description> </method> <method name="append"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="integer" type="int"> + <argument index="0" name="value" type="int"> </argument> <description> Appends an element at the end of the array (alias of [method push_back]). @@ -57,9 +57,9 @@ <method name="insert"> <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="at_index" type="int"> </argument> - <argument index="1" name="integer" type="int"> + <argument index="1" name="value" type="int"> </argument> <description> Inserts a new integer at a given position in the array. The position must be valid, or at the end of the array ([code]idx == size()[/code]). @@ -73,9 +73,9 @@ </description> </method> <method name="push_back"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="integer" type="int"> + <argument index="0" name="value" type="int"> </argument> <description> Appends a value to the array. @@ -84,16 +84,16 @@ <method name="remove"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> <description> Removes an element from the array by index. </description> </method> <method name="resize"> - <return type="void"> + <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="new_size" type="int"> </argument> <description> Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size. @@ -102,9 +102,9 @@ <method name="set"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> - <argument index="1" name="integer" type="int"> + <argument index="1" name="value" type="int"> </argument> <description> Changes the integer at the given index. @@ -124,6 +124,22 @@ Sorts the elements of the array in ascending order. </description> </method> + <method name="subarray"> + <return type="PackedInt64Array"> + </return> + <argument index="0" name="from" type="int"> + </argument> + <argument index="1" name="to" type="int"> + </argument> + <description> + </description> + </method> + <method name="to_byte_array"> + <return type="PackedByteArray"> + </return> + <description> + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/PackedStringArray.xml b/doc/classes/PackedStringArray.xml index 5f3a16ac73..7c710cf0fb 100644 --- a/doc/classes/PackedStringArray.xml +++ b/doc/classes/PackedStringArray.xml @@ -21,9 +21,9 @@ </description> </method> <method name="append"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="string" type="String"> + <argument index="0" name="value" type="String"> </argument> <description> Appends an element at the end of the array (alias of [method push_back]). @@ -57,9 +57,9 @@ <method name="insert"> <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="at_index" type="int"> </argument> - <argument index="1" name="string" type="String"> + <argument index="1" name="value" type="String"> </argument> <description> Inserts a new element at a given position in the array. The position must be valid, or at the end of the array ([code]idx == size()[/code]). @@ -73,9 +73,9 @@ </description> </method> <method name="push_back"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="string" type="String"> + <argument index="0" name="value" type="String"> </argument> <description> Appends a string element at end of the array. @@ -84,16 +84,16 @@ <method name="remove"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> <description> Removes an element from the array by index. </description> </method> <method name="resize"> - <return type="void"> + <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="new_size" type="int"> </argument> <description> Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size. @@ -102,9 +102,9 @@ <method name="set"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> - <argument index="1" name="string" type="String"> + <argument index="1" name="value" type="String"> </argument> <description> Changes the [String] at the given index. @@ -124,6 +124,22 @@ Sorts the elements of the array in ascending order. </description> </method> + <method name="subarray"> + <return type="PackedStringArray"> + </return> + <argument index="0" name="from" type="int"> + </argument> + <argument index="1" name="to" type="int"> + </argument> + <description> + </description> + </method> + <method name="to_byte_array"> + <return type="PackedByteArray"> + </return> + <description> + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/PackedVector2Array.xml b/doc/classes/PackedVector2Array.xml index cb62aea95c..98034afc93 100644 --- a/doc/classes/PackedVector2Array.xml +++ b/doc/classes/PackedVector2Array.xml @@ -21,9 +21,9 @@ </description> </method> <method name="append"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="vector2" type="Vector2"> + <argument index="0" name="value" type="Vector2"> </argument> <description> Appends an element at the end of the array (alias of [method push_back]). @@ -57,9 +57,9 @@ <method name="insert"> <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="at_index" type="int"> </argument> - <argument index="1" name="vector2" type="Vector2"> + <argument index="1" name="value" type="Vector2"> </argument> <description> Inserts a new element at a given position in the array. The position must be valid, or at the end of the array ([code]idx == size()[/code]). @@ -73,9 +73,9 @@ </description> </method> <method name="push_back"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="vector2" type="Vector2"> + <argument index="0" name="value" type="Vector2"> </argument> <description> Inserts a [Vector2] at the end. @@ -84,16 +84,16 @@ <method name="remove"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> <description> Removes an element from the array by index. </description> </method> <method name="resize"> - <return type="void"> + <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="new_size" type="int"> </argument> <description> Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size. @@ -102,9 +102,9 @@ <method name="set"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> - <argument index="1" name="vector2" type="Vector2"> + <argument index="1" name="value" type="Vector2"> </argument> <description> Changes the [Vector2] at the given index. @@ -124,6 +124,22 @@ Sorts the elements of the array in ascending order. </description> </method> + <method name="subarray"> + <return type="PackedVector2Array"> + </return> + <argument index="0" name="from" type="int"> + </argument> + <argument index="1" name="to" type="int"> + </argument> + <description> + </description> + </method> + <method name="to_byte_array"> + <return type="PackedByteArray"> + </return> + <description> + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/PackedVector3Array.xml b/doc/classes/PackedVector3Array.xml index f268fbcc83..3db33fbcd9 100644 --- a/doc/classes/PackedVector3Array.xml +++ b/doc/classes/PackedVector3Array.xml @@ -20,9 +20,9 @@ </description> </method> <method name="append"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="vector3" type="Vector3"> + <argument index="0" name="value" type="Vector3"> </argument> <description> Appends an element at the end of the array (alias of [method push_back]). @@ -56,9 +56,9 @@ <method name="insert"> <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="at_index" type="int"> </argument> - <argument index="1" name="vector3" type="Vector3"> + <argument index="1" name="value" type="Vector3"> </argument> <description> Inserts a new element at a given position in the array. The position must be valid, or at the end of the array ([code]idx == size()[/code]). @@ -72,9 +72,9 @@ </description> </method> <method name="push_back"> - <return type="void"> + <return type="bool"> </return> - <argument index="0" name="vector3" type="Vector3"> + <argument index="0" name="value" type="Vector3"> </argument> <description> Inserts a [Vector3] at the end. @@ -83,16 +83,16 @@ <method name="remove"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> <description> Removes an element from the array by index. </description> </method> <method name="resize"> - <return type="void"> + <return type="int"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="new_size" type="int"> </argument> <description> Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size. @@ -101,9 +101,9 @@ <method name="set"> <return type="void"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="index" type="int"> </argument> - <argument index="1" name="vector3" type="Vector3"> + <argument index="1" name="value" type="Vector3"> </argument> <description> Changes the [Vector3] at the given index. @@ -123,6 +123,22 @@ Sorts the elements of the array in ascending order. </description> </method> + <method name="subarray"> + <return type="PackedVector3Array"> + </return> + <argument index="0" name="from" type="int"> + </argument> + <argument index="1" name="to" type="int"> + </argument> + <description> + </description> + </method> + <method name="to_byte_array"> + <return type="PackedByteArray"> + </return> + <description> + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/Plane.xml b/doc/classes/Plane.xml index d420e6ccdc..9352eee1eb 100644 --- a/doc/classes/Plane.xml +++ b/doc/classes/Plane.xml @@ -77,7 +77,7 @@ </description> </method> <method name="intersect_3"> - <return type="Vector3"> + <return type="Variant"> </return> <argument index="0" name="b" type="Plane"> </argument> @@ -88,7 +88,7 @@ </description> </method> <method name="intersects_ray"> - <return type="Vector3"> + <return type="Variant"> </return> <argument index="0" name="from" type="Vector3"> </argument> @@ -99,11 +99,11 @@ </description> </method> <method name="intersects_segment"> - <return type="Vector3"> + <return type="Variant"> </return> - <argument index="0" name="begin" type="Vector3"> + <argument index="0" name="from" type="Vector3"> </argument> - <argument index="1" name="end" type="Vector3"> + <argument index="1" name="to" type="Vector3"> </argument> <description> Returns the intersection point of a segment from position [code]begin[/code] to position [code]end[/code] with this plane. If no intersection is found, [code]null[/code] is returned. @@ -112,7 +112,7 @@ <method name="is_equal_approx"> <return type="bool"> </return> - <argument index="0" name="plane" type="Plane"> + <argument index="0" name="to_plane" type="Plane"> </argument> <description> Returns [code]true[/code] if this plane and [code]plane[/code] are approximately equal, by running [method @GDScript.is_equal_approx] on each component. @@ -121,7 +121,7 @@ <method name="is_point_over"> <return type="bool"> </return> - <argument index="0" name="point" type="Vector3"> + <argument index="0" name="plane" type="Vector3"> </argument> <description> Returns [code]true[/code] if [code]point[/code] is located above the plane. diff --git a/doc/classes/PointLight2D.xml b/doc/classes/PointLight2D.xml new file mode 100644 index 0000000000..9337bc8351 --- /dev/null +++ b/doc/classes/PointLight2D.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="PointLight2D" inherits="Light2D" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="height" type="float" setter="set_height" getter="get_height" default="0.0"> + The height of the light. Used with 2D normal mapping. + </member> + <member name="offset" type="Vector2" setter="set_texture_offset" getter="get_texture_offset" default="Vector2( 0, 0 )"> + The offset of the light's [member texture]. + </member> + <member name="texture" type="Texture2D" setter="set_texture" getter="get_texture"> + [Texture2D] used for the light's appearance. + </member> + <member name="texture_scale" type="float" setter="set_texture_scale" getter="get_texture_scale" default="1.0"> + The [member texture]'s scale factor. + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/Polygon2D.xml b/doc/classes/Polygon2D.xml index 335df1ac3f..3aca83658d 100644 --- a/doc/classes/Polygon2D.xml +++ b/doc/classes/Polygon2D.xml @@ -101,10 +101,6 @@ <member name="invert_enable" type="bool" setter="set_invert" getter="get_invert" default="false"> If [code]true[/code], polygon will be inverted, containing the area outside the defined points and extending to the [code]invert_border[/code]. </member> - <member name="normal_map" type="Texture2D" setter="set_normal_map" getter="get_normal_map"> - The normal map gives depth to the Polygon2D. - [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines. - </member> <member name="offset" type="Vector2" setter="set_offset" getter="get_offset" default="Vector2( 0, 0 )"> The offset applied to each vertex. </member> @@ -114,14 +110,8 @@ </member> <member name="polygons" type="Array" setter="set_polygons" getter="get_polygons" default="[ ]"> </member> - <member name="shininess" type="float" setter="set_shininess" getter="get_shininess" default="1.0"> - </member> <member name="skeleton" type="NodePath" setter="set_skeleton" getter="get_skeleton" default="NodePath("")"> </member> - <member name="specular_color" type="Color" setter="set_specular_color" getter="get_specular_color" default="Color( 1, 1, 1, 1 )"> - </member> - <member name="specular_map" type="Texture2D" setter="set_specular_map" getter="get_specular_map"> - </member> <member name="texture" type="Texture2D" setter="set_texture" getter="get_texture"> The polygon's fill texture. Use [code]uv[/code] to set texture coordinates. </member> diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 91998ead34..856c2e7c37 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -818,6 +818,8 @@ <member name="logging/file_logging/max_log_files" type="int" setter="" getter="" default="5"> Specifies the maximum amount of log files allowed (used for rotation). </member> + <member name="memory/limits/command_queue/multithreading_queue_size_kb" type="int" setter="" getter="" default="256"> + </member> <member name="memory/limits/message_queue/max_size_kb" type="int" setter="" getter="" default="4096"> Godot uses a message queue to defer some function calls. If you run out of space on it (you will see an error), you can increase the size here. </member> @@ -1004,8 +1006,11 @@ </member> <member name="rendering/limits/time/time_rollover_secs" type="float" setter="" getter="" default="3600"> </member> - <member name="rendering/quality/2d/use_pixel_snap" type="bool" setter="" getter="" default="false"> - If [code]true[/code], forces snapping of polygons to pixels in 2D rendering. May help in some pixel art styles. + <member name="rendering/quality/2d/snap_2d_transforms_to_pixel" type="bool" setter="" getter="" default="false"> + </member> + <member name="rendering/quality/2d/snap_2d_vertices_to_pixel" type="bool" setter="" getter="" default="false"> + </member> + <member name="rendering/quality/2d_shadow_atlas/size" type="int" setter="" getter="" default="2048"> </member> <member name="rendering/quality/depth_of_field/depth_of_field_bokeh_quality" type="int" setter="" getter="" default="2"> Sets the quality of the depth of field effect. Higher quality takes more samples, which is slower but looks smoother. @@ -1102,6 +1107,8 @@ </member> <member name="rendering/quality/screen_filters/screen_space_roughness_limiter_limit" type="float" setter="" getter="" default="0.18"> </member> + <member name="rendering/quality/screen_filters/use_debanding" type="bool" setter="" getter="" default="false"> + </member> <member name="rendering/quality/screen_space_reflection/roughness_quality" type="int" setter="" getter="" default="1"> Sets the quality for rough screen-space reflections. Turning off will make all screen space reflections sharp, while higher values make rough reflections look better. </member> diff --git a/doc/classes/Quat.xml b/doc/classes/Quat.xml index 6c95e303b8..76cfa0d99d 100644 --- a/doc/classes/Quat.xml +++ b/doc/classes/Quat.xml @@ -16,45 +16,45 @@ <method name="Quat"> <return type="Quat"> </return> - <argument index="0" name="from" type="Basis"> + <argument index="0" name="x" type="float"> + </argument> + <argument index="1" name="y" type="float"> + </argument> + <argument index="2" name="z" type="float"> + </argument> + <argument index="3" name="w" type="float"> </argument> <description> - Constructs a quaternion from the given [Basis]. + Constructs a quaternion defined by the given values. </description> </method> <method name="Quat"> <return type="Quat"> </return> - <argument index="0" name="euler" type="Vector3"> + <argument index="0" name="axis" type="Vector3"> + </argument> + <argument index="1" name="angle" type="float"> </argument> <description> - Constructs a quaternion that will perform a rotation specified by Euler angles (in the YXZ convention: when decomposing, first Z, then X, and Y last), given in the vector format as (X angle, Y angle, Z angle). + Constructs a quaternion that will rotate around the given axis by the specified angle. The axis must be a normalized vector. </description> </method> <method name="Quat"> <return type="Quat"> </return> - <argument index="0" name="axis" type="Vector3"> - </argument> - <argument index="1" name="angle" type="float"> + <argument index="0" name="euler" type="Vector3"> </argument> <description> - Constructs a quaternion that will rotate around the given axis by the specified angle. The axis must be a normalized vector. + Constructs a quaternion that will perform a rotation specified by Euler angles (in the YXZ convention: when decomposing, first Z, then X, and Y last), given in the vector format as (X angle, Y angle, Z angle). </description> </method> <method name="Quat"> <return type="Quat"> </return> - <argument index="0" name="x" type="float"> - </argument> - <argument index="1" name="y" type="float"> - </argument> - <argument index="2" name="z" type="float"> - </argument> - <argument index="3" name="w" type="float"> + <argument index="0" name="from" type="Basis"> </argument> <description> - Constructs a quaternion defined by the given values. + Constructs a quaternion from the given [Basis]. </description> </method> <method name="cubic_slerp"> @@ -75,7 +75,7 @@ <method name="dot"> <return type="float"> </return> - <argument index="0" name="b" type="Quat"> + <argument index="0" name="with" type="Quat"> </argument> <description> Returns the dot product of two quaternions. @@ -98,7 +98,7 @@ <method name="is_equal_approx"> <return type="bool"> </return> - <argument index="0" name="quat" type="Quat"> + <argument index="0" name="to" type="Quat"> </argument> <description> Returns [code]true[/code] if this quaterion and [code]quat[/code] are approximately equal, by running [method @GDScript.is_equal_approx] on each component. @@ -132,26 +132,6 @@ Returns a copy of the quaternion, normalized to unit length. </description> </method> - <method name="set_axis_angle"> - <return type="void"> - </return> - <argument index="0" name="axis" type="Vector3"> - </argument> - <argument index="1" name="angle" type="float"> - </argument> - <description> - Sets the quaternion to a rotation which rotates around axis by the specified angle, in radians. The axis must be a normalized vector. - </description> - </method> - <method name="set_euler"> - <return type="void"> - </return> - <argument index="0" name="euler" type="Vector3"> - </argument> - <description> - Sets the quaternion to a rotation specified by Euler angles (in the YXZ convention: when decomposing, first Z, then X, and Y last), given in the vector format as (X angle, Y angle, Z angle). - </description> - </method> <method name="slerp"> <return type="Quat"> </return> @@ -175,15 +155,6 @@ Returns the result of the spherical linear interpolation between this quaternion and [code]to[/code] by amount [code]weight[/code], but without checking if the rotation path is not bigger than 90 degrees. </description> </method> - <method name="xform"> - <return type="Vector3"> - </return> - <argument index="0" name="v" type="Vector3"> - </argument> - <description> - Returns a vector transformed (multiplied) by this quaternion. - </description> - </method> </methods> <members> <member name="w" type="float" setter="" getter="" default="1.0"> diff --git a/doc/classes/RandomNumberGenerator.xml b/doc/classes/RandomNumberGenerator.xml index d4f9517dd1..dcb75dc275 100644 --- a/doc/classes/RandomNumberGenerator.xml +++ b/doc/classes/RandomNumberGenerator.xml @@ -74,9 +74,10 @@ </method> </methods> <members> - <member name="seed" type="int" setter="set_seed" getter="get_seed" default="-6398989897141750821"> + <member name="seed" type="int" setter="set_seed" getter="get_seed" default="0"> The seed used by the random number generator. A given seed will give a reproducible sequence of pseudo-random numbers. [b]Note:[/b] The RNG does not have an avalanche effect, and can output similar random streams given similar seeds. Consider using a hash function to improve your seed quality if they're sourced externally. + [b]Note:[/b] The default value of this property is pseudo-random, and changes when calling [method randomize]. The [code]0[/code] value documented here is a placeholder, and not the actual default seed. </member> </members> <constants> diff --git a/doc/classes/Rect2.xml b/doc/classes/Rect2.xml index aaeaa7629d..a72ba35a98 100644 --- a/doc/classes/Rect2.xml +++ b/doc/classes/Rect2.xml @@ -108,7 +108,7 @@ </argument> <argument index="2" name="right" type="float"> </argument> - <argument index="3" name=" bottom" type="float"> + <argument index="3" name="bottom" type="float"> </argument> <description> Returns a copy of the [Rect2] grown a given amount of units towards each direction individually. diff --git a/doc/classes/Rect2i.xml b/doc/classes/Rect2i.xml index 8b29daa264..de2932e816 100644 --- a/doc/classes/Rect2i.xml +++ b/doc/classes/Rect2i.xml @@ -15,9 +15,9 @@ <method name="Rect2i"> <return type="Rect2i"> </return> - <argument index="0" name="position" type="Vector2"> + <argument index="0" name="position" type="Vector2i"> </argument> - <argument index="1" name="size" type="Vector2"> + <argument index="1" name="size" type="Vector2i"> </argument> <description> Constructs a [Rect2i] by position and size. @@ -106,7 +106,7 @@ </argument> <argument index="2" name="right" type="int"> </argument> - <argument index="3" name=" bottom" type="int"> + <argument index="3" name="bottom" type="int"> </argument> <description> Returns a copy of the [Rect2i] grown a given amount of units towards each direction individually. diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 857c13deb5..5830a8452c 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -404,28 +404,6 @@ The mode of the light, see [enum CanvasLightMode] constants. </description> </method> - <method name="canvas_light_set_scale"> - <return type="void"> - </return> - <argument index="0" name="light" type="RID"> - </argument> - <argument index="1" name="scale" type="float"> - </argument> - <description> - Sets the texture's scale factor of the light. Equivalent to [member Light2D.texture_scale]. - </description> - </method> - <method name="canvas_light_set_shadow_buffer_size"> - <return type="void"> - </return> - <argument index="0" name="light" type="RID"> - </argument> - <argument index="1" name="size" type="int"> - </argument> - <description> - Sets the width of the shadow buffer, size gets scaled to the next power of two for this. - </description> - </method> <method name="canvas_light_set_shadow_color"> <return type="void"> </return> @@ -478,7 +456,7 @@ <argument index="1" name="texture" type="RID"> </argument> <description> - Sets texture to be used by light. Equivalent to [member Light2D.texture]. + Sets the texture to be used by a [PointLight2D]. Equivalent to [member PointLight2D.texture]. </description> </method> <method name="canvas_light_set_texture_offset"> @@ -489,7 +467,18 @@ <argument index="1" name="offset" type="Vector2"> </argument> <description> - Sets the offset of the light's texture. Equivalent to [member Light2D.offset]. + Sets the offset of a [PointLight2D]'s texture. Equivalent to [member PointLight2D.offset]. + </description> + </method> + <method name="canvas_light_set_texture_scale"> + <return type="void"> + </return> + <argument index="0" name="light" type="RID"> + </argument> + <argument index="1" name="scale" type="float"> + </argument> + <description> + Sets the scale factor of a [PointLight2D]'s texture. Equivalent to [member PointLight2D.texture_scale]. </description> </method> <method name="canvas_light_set_transform"> @@ -708,6 +697,8 @@ </argument> <argument index="7" name="height_density" type="float"> </argument> + <argument index="8" name="aerial_perspective" type="float"> + </argument> <description> </description> </method> @@ -2965,6 +2956,16 @@ Sets when the viewport should be updated. See [enum ViewportUpdateMode] constants for options. </description> </method> + <method name="viewport_set_use_debanding"> + <return type="void"> + </return> + <argument index="0" name="viewport" type="RID"> + </argument> + <argument index="1" name="enable" type="bool"> + </argument> + <description> + </description> + </method> <method name="viewport_set_use_xr"> <return type="void"> </return> @@ -3674,18 +3675,25 @@ <constant name="CANVAS_ITEM_TEXTURE_REPEAT_MAX" value="4" enum="CanvasItemTextureRepeat"> Max value for [enum CanvasItemTextureRepeat] enum. </constant> - <constant name="CANVAS_LIGHT_MODE_ADD" value="0" enum="CanvasLightMode"> + <constant name="CANVAS_GROUP_MODE_DISABLED" value="0" enum="CanvasGroupMode"> + </constant> + <constant name="CANVAS_GROUP_MODE_OPAQUE" value="1" enum="CanvasGroupMode"> + </constant> + <constant name="CANVAS_GROUP_MODE_TRANSPARENT" value="2" enum="CanvasGroupMode"> + </constant> + <constant name="CANVAS_LIGHT_MODE_POINT" value="0" enum="CanvasLightMode"> + </constant> + <constant name="CANVAS_LIGHT_MODE_DIRECTIONAL" value="1" enum="CanvasLightMode"> + </constant> + <constant name="CANVAS_LIGHT_BLEND_MODE_ADD" value="0" enum="CanvasLightBlendMode"> Adds light color additive to the canvas. </constant> - <constant name="CANVAS_LIGHT_MODE_SUB" value="1" enum="CanvasLightMode"> + <constant name="CANVAS_LIGHT_BLEND_MODE_SUB" value="1" enum="CanvasLightBlendMode"> Adds light color subtractive to the canvas. </constant> - <constant name="CANVAS_LIGHT_MODE_MIX" value="2" enum="CanvasLightMode"> + <constant name="CANVAS_LIGHT_BLEND_MODE_MIX" value="2" enum="CanvasLightBlendMode"> The light adds color depending on transparency. </constant> - <constant name="CANVAS_LIGHT_MODE_MASK" value="3" enum="CanvasLightMode"> - The light adds color depending on mask. - </constant> <constant name="CANVAS_LIGHT_FILTER_NONE" value="0" enum="CanvasLightShadowFilter"> Do not apply a filter to canvas light shadows. </constant> diff --git a/doc/classes/Signal.xml b/doc/classes/Signal.xml index 1a05c02b60..51490caf6f 100644 --- a/doc/classes/Signal.xml +++ b/doc/classes/Signal.xml @@ -33,7 +33,7 @@ </description> </method> <method name="disconnect"> - <return type="Variant"> + <return type="void"> </return> <argument index="0" name="callable" type="Callable"> </argument> diff --git a/doc/classes/Sprite2D.xml b/doc/classes/Sprite2D.xml index 8205889ea7..c56596423d 100644 --- a/doc/classes/Sprite2D.xml +++ b/doc/classes/Sprite2D.xml @@ -53,10 +53,6 @@ <member name="hframes" type="int" setter="set_hframes" getter="get_hframes" default="1"> The number of columns in the sprite sheet. </member> - <member name="normal_map" type="Texture2D" setter="set_normal_map" getter="get_normal_map"> - The normal map gives depth to the Sprite2D. - [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines. - </member> <member name="offset" type="Vector2" setter="set_offset" getter="get_offset" default="Vector2( 0, 0 )"> The texture's drawing offset. </member> @@ -69,15 +65,6 @@ <member name="region_rect" type="Rect2" setter="set_region_rect" getter="get_region_rect" default="Rect2( 0, 0, 0, 0 )"> The region of the atlas texture to display. [member region_enabled] must be [code]true[/code]. </member> - <member name="shininess" type="float" setter="set_shininess" getter="get_shininess" default="1.0"> - Strength of the specular light effect of this [Sprite2D]. - </member> - <member name="specular_color" type="Color" setter="set_specular_color" getter="get_specular_color" default="Color( 1, 1, 1, 1 )"> - The color of the specular light effect. - </member> - <member name="specular_map" type="Texture2D" setter="set_specular_map" getter="get_specular_map"> - The specular map is used for more control on the shininess effect. - </member> <member name="texture" type="Texture2D" setter="set_texture" getter="get_texture"> [Texture2D] object to draw. </member> diff --git a/doc/classes/String.xml b/doc/classes/String.xml index 4034a5ee07..fcd8f57cd1 100644 --- a/doc/classes/String.xml +++ b/doc/classes/String.xml @@ -314,6 +314,14 @@ Returns the bigrams (pairs of consecutive letters) of this string. </description> </method> + <method name="bin_to_int"> + <return type="int"> + </return> + <argument index="0" name="with_prefix" type="bool" default="true"> + </argument> + <description> + </description> + </method> <method name="c_escape"> <return type="String"> </return> @@ -397,17 +405,6 @@ Returns [code]true[/code] if the string ends with the given string. </description> </method> - <method name="erase"> - <return type="void"> - </return> - <argument index="0" name="position" type="int"> - </argument> - <argument index="1" name="chars" type="int"> - </argument> - <description> - Erases [code]chars[/code] characters from the string starting from [code]position[/code]. - </description> - </method> <method name="find"> <return type="int"> </return> @@ -485,10 +482,13 @@ <method name="hex_to_int"> <return type="int"> </return> + <argument index="0" name="with_prefix" type="bool" default="true"> + </argument> <description> - Converts a string containing a hexadecimal number into an integer. Hexadecimal strings are expected to be prefixed with "[code]0x[/code]" otherwise [code]0[/code] is returned. + Converts a string containing a hexadecimal number into a decimal integer. If [code]with_prefix[/code] is [code]true[/code], the hexadecimal string should start with the [code]0x[/code] prefix, otherwise [code]0[/code] is returned. [codeblock] print("0xff".hex_to_int()) # Print "255" + print("ab".hex_to_int(false)) # Print "171" [/codeblock] </description> </method> @@ -512,20 +512,6 @@ [/codeblock] </description> </method> - <method name="humanize_size"> - <return type="String"> - </return> - <argument index="0" name="size" type="int"> - </argument> - <description> - Converts [code]size[/code] represented as number of bytes to human-readable format using internationalized set of data size units, namely: B, KiB, MiB, GiB, TiB, PiB, EiB. Note that the next smallest unit is picked automatically to hold at most 1024 units. - [codeblock] - var bytes = 133790307 - var size = String.humanize_size(bytes) - print(size) # prints "127.5 MiB" - [/codeblock] - </description> - </method> <method name="insert"> <return type="String"> </return> @@ -990,11 +976,11 @@ Returns part of the string from the position [code]from[/code] with length [code]len[/code]. Argument [code]len[/code] is optional and using [code]-1[/code] will return remaining characters from given position. </description> </method> - <method name="to_ascii"> + <method name="to_ascii_buffer"> <return type="PackedByteArray"> </return> <description> - Converts the String (which is a character array) to ASCII/Latin-1 encoded [PackedByteArray] (which is an array of bytes). The conversion is faster compared to [method to_utf8], as this method assumes that all the characters in the String are ASCII/Latin-1 characters, unsupported characters are replaced with spaces. + Converts the String (which is a character array) to ASCII/Latin-1 encoded [PackedByteArray] (which is an array of bytes). The conversion is faster compared to [method to_utf8_buffer], as this method assumes that all the characters in the String are ASCII/Latin-1 characters, unsupported characters are replaced with spaces. </description> </method> <method name="to_float"> @@ -1025,25 +1011,25 @@ Returns the string converted to uppercase. </description> </method> - <method name="to_utf16"> + <method name="to_utf16_buffer"> <return type="PackedByteArray"> </return> <description> Converts the String (which is an array of characters) to UTF-16 encoded [PackedByteArray] (which is an array of bytes). </description> </method> - <method name="to_utf32"> + <method name="to_utf32_buffer"> <return type="PackedByteArray"> </return> <description> Converts the String (which is an array of characters) to UTF-32 encoded [PackedByteArray] (which is an array of bytes). </description> </method> - <method name="to_utf8"> + <method name="to_utf8_buffer"> <return type="PackedByteArray"> </return> <description> - Converts the String (which is an array of characters) to UTF-8 encode [PackedByteArray] (which is an array of bytes). The conversion is a bit slower than [method to_ascii], but supports all UTF-8 characters. Therefore, you should prefer this function over [method to_ascii]. + Converts the String (which is an array of characters) to UTF-8 encode [PackedByteArray] (which is an array of bytes). The conversion is a bit slower than [method to_ascii_buffer], but supports all UTF-8 characters. Therefore, you should prefer this function over [method to_ascii_buffer]. </description> </method> <method name="trim_prefix"> @@ -1067,8 +1053,10 @@ <method name="xml_escape"> <return type="String"> </return> + <argument index="0" name="escape_quotes" type="bool" default="false"> + </argument> <description> - Returns a copy of the string with special characters escaped using the XML standard. + Returns a copy of the string with special characters escaped using the XML standard. If [code]escape_quotes[/code] is [code]true[/code], the single quote ([code]'[/code]) and double quote ([code]"[/code]) characters are also escaped. </description> </method> <method name="xml_unescape"> diff --git a/doc/classes/StyleBoxTexture.xml b/doc/classes/StyleBoxTexture.xml index f8aa14cb2b..6f5577b61b 100644 --- a/doc/classes/StyleBoxTexture.xml +++ b/doc/classes/StyleBoxTexture.xml @@ -119,10 +119,6 @@ <member name="modulate_color" type="Color" setter="set_modulate" getter="get_modulate" default="Color( 1, 1, 1, 1 )"> Modulates the color of the texture when this style box is drawn. </member> - <member name="normal_map" type="Texture2D" setter="set_normal_map" getter="get_normal_map"> - The normal map to use when drawing this style box. - [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines. - </member> <member name="region_rect" type="Rect2" setter="set_region_rect" getter="get_region_rect" default="Rect2( 0, 0, 0, 0 )"> Species a sub-region of the texture to use. This is equivalent to first wrapping the texture in an [AtlasTexture] with the same region. diff --git a/doc/classes/Tabs.xml b/doc/classes/Tabs.xml index ef1f370185..15c2d3504c 100644 --- a/doc/classes/Tabs.xml +++ b/doc/classes/Tabs.xml @@ -4,7 +4,7 @@ Tabs control. </brief_description> <description> - Simple tabs control, similar to [TabContainer] but is only in charge of drawing tabs, not interact with children. + Simple tabs control, similar to [TabContainer] but is only in charge of drawing tabs, not interacting with children. </description> <tutorials> </tutorials> diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index a23a4936f8..53d706db2d 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -213,6 +213,12 @@ Returns the [PopupMenu] of this [TextEdit]. By default, this menu is displayed when right-clicking on the [TextEdit]. </description> </method> + <method name="get_selection_column" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> <method name="get_selection_from_column" qualifiers="const"> <return type="int"> </return> @@ -227,6 +233,18 @@ Returns the selection begin line. </description> </method> + <method name="get_selection_line" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="get_selection_mode" qualifiers="const"> + <return type="int" enum="TextEdit.SelectionMode"> + </return> + <description> + </description> + </method> <method name="get_selection_text" qualifiers="const"> <return type="String"> </return> @@ -555,6 +573,18 @@ <description> </description> </method> + <method name="set_selection_mode"> + <return type="void"> + </return> + <argument index="0" name="mode" type="int" enum="TextEdit.SelectionMode"> + </argument> + <argument index="1" name="line" type="int" default="-1"> + </argument> + <argument index="2" name="column" type="int" default="-1"> + </argument> + <description> + </description> + </method> <method name="toggle_fold_line"> <return type="void"> </return> @@ -732,6 +762,16 @@ <constant name="SEARCH_BACKWARDS" value="4" enum="SearchFlags"> Search from end to beginning. </constant> + <constant name="SELECTION_MODE_NONE" value="0" enum="SelectionMode"> + </constant> + <constant name="SELECTION_MODE_SHIFT" value="1" enum="SelectionMode"> + </constant> + <constant name="SELECTION_MODE_POINTER" value="2" enum="SelectionMode"> + </constant> + <constant name="SELECTION_MODE_WORD" value="3" enum="SelectionMode"> + </constant> + <constant name="SELECTION_MODE_LINE" value="4" enum="SelectionMode"> + </constant> <constant name="GUTTER_TYPE_STRING" value="0" enum="GutterType"> </constant> <constant name="GUTTER_TPYE_ICON" value="1" enum="GutterType"> diff --git a/doc/classes/Texture2D.xml b/doc/classes/Texture2D.xml index f283efdc3d..ff8b439a3d 100644 --- a/doc/classes/Texture2D.xml +++ b/doc/classes/Texture2D.xml @@ -22,16 +22,6 @@ </argument> <argument index="3" name="transpose" type="bool" default="false"> </argument> - <argument index="4" name="normal_map" type="Texture2D" default="null"> - </argument> - <argument index="5" name="specular_map" type="Texture2D" default="null"> - </argument> - <argument index="6" name="specular_color_shininess" type="Color" default="Color( 1, 1, 1, 1 )"> - </argument> - <argument index="7" name="texture_filter" type="int" enum="RenderingServer.CanvasItemTextureFilter" default="0"> - </argument> - <argument index="8" name="texture_repeat" type="int" enum="RenderingServer.CanvasItemTextureRepeat" default="0"> - </argument> <description> Draws the texture using a [CanvasItem] with the [RenderingServer] API at the specified [code]position[/code]. </description> @@ -49,16 +39,6 @@ </argument> <argument index="4" name="transpose" type="bool" default="false"> </argument> - <argument index="5" name="normal_map" type="Texture2D" default="null"> - </argument> - <argument index="6" name="specular_map" type="Texture2D" default="null"> - </argument> - <argument index="7" name="specular_color_shininess" type="Color" default="Color( 1, 1, 1, 1 )"> - </argument> - <argument index="8" name="texture_filter" type="int" enum="RenderingServer.CanvasItemTextureFilter" default="0"> - </argument> - <argument index="9" name="texture_repeat" type="int" enum="RenderingServer.CanvasItemTextureRepeat" default="0"> - </argument> <description> Draws the texture using a [CanvasItem] with the [RenderingServer] API. </description> @@ -76,17 +56,7 @@ </argument> <argument index="4" name="transpose" type="bool" default="false"> </argument> - <argument index="5" name="normal_map" type="Texture2D" default="null"> - </argument> - <argument index="6" name="specular_map" type="Texture2D" default="null"> - </argument> - <argument index="7" name="specular_color_shininess" type="Color" default="Color( 1, 1, 1, 1 )"> - </argument> - <argument index="8" name="texture_filter" type="int" enum="RenderingServer.CanvasItemTextureFilter" default="0"> - </argument> - <argument index="9" name="texture_repeat" type="int" enum="RenderingServer.CanvasItemTextureRepeat" default="0"> - </argument> - <argument index="10" name="clip_uv" type="bool" default="true"> + <argument index="5" name="clip_uv" type="bool" default="true"> </argument> <description> Draws a part of the texture using a [CanvasItem] with the [RenderingServer] API. diff --git a/doc/classes/TileSet.xml b/doc/classes/TileSet.xml index 9ab9d9ca7a..adc5880c71 100644 --- a/doc/classes/TileSet.xml +++ b/doc/classes/TileSet.xml @@ -389,15 +389,6 @@ Returns the offset of the tile's navigation polygon. </description> </method> - <method name="tile_get_normal_map" qualifiers="const"> - <return type="Texture2D"> - </return> - <argument index="0" name="id" type="int"> - </argument> - <description> - Returns the tile's normal map texture. - </description> - </method> <method name="tile_get_occluder_offset" qualifiers="const"> <return type="Vector2"> </return> @@ -600,18 +591,6 @@ Sets an offset for the tile's navigation polygon. </description> </method> - <method name="tile_set_normal_map"> - <return type="void"> - </return> - <argument index="0" name="id" type="int"> - </argument> - <argument index="1" name="normal_map" type="Texture2D"> - </argument> - <description> - Sets the tile's normal map texture. - [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines. - </description> - </method> <method name="tile_set_occluder_offset"> <return type="void"> </return> diff --git a/doc/classes/Transform.xml b/doc/classes/Transform.xml index 52dda75dff..8e539e64f7 100644 --- a/doc/classes/Transform.xml +++ b/doc/classes/Transform.xml @@ -79,7 +79,7 @@ <method name="interpolate_with"> <return type="Transform"> </return> - <argument index="0" name="transform" type="Transform"> + <argument index="0" name="xform" type="Transform"> </argument> <argument index="1" name="weight" type="float"> </argument> @@ -97,7 +97,7 @@ <method name="is_equal_approx"> <return type="bool"> </return> - <argument index="0" name="transform" type="Transform"> + <argument index="0" name="xform" type="Transform"> </argument> <description> Returns [code]true[/code] if this transform and [code]transform[/code] are approximately equal, by calling [code]is_equal_approx[/code] on each component. @@ -153,24 +153,6 @@ Unlike [method rotated] and [method scaled], this does not use matrix multiplication. </description> </method> - <method name="xform"> - <return type="Variant"> - </return> - <argument index="0" name="v" type="Variant"> - </argument> - <description> - Transforms the given [Vector3], [Plane], [AABB], or [PackedVector3Array] by this transform. - </description> - </method> - <method name="xform_inv"> - <return type="Variant"> - </return> - <argument index="0" name="v" type="Variant"> - </argument> - <description> - Inverse-transforms the given [Vector3], [Plane], [AABB], or [PackedVector3Array] by this transform. - </description> - </method> </methods> <members> <member name="basis" type="Basis" setter="" getter="" default="Basis( 1, 0, 0, 0, 1, 0, 0, 0, 1 )"> diff --git a/doc/classes/Transform2D.xml b/doc/classes/Transform2D.xml index b23bb4d33b..66adeab3a6 100644 --- a/doc/classes/Transform2D.xml +++ b/doc/classes/Transform2D.xml @@ -17,10 +17,12 @@ <method name="Transform2D"> <return type="Transform2D"> </return> - <argument index="0" name="from" type="Transform"> + <argument index="0" name="rotation" type="float"> + </argument> + <argument index="1" name="position" type="Vector2"> </argument> <description> - Constructs the transform from a 3D [Transform]. + Constructs the transform from a given angle (in radians) and position. </description> </method> <method name="Transform2D"> @@ -39,12 +41,10 @@ <method name="Transform2D"> <return type="Transform2D"> </return> - <argument index="0" name="rotation" type="float"> - </argument> - <argument index="1" name="position" type="Vector2"> + <argument index="0" name="from" type="Transform"> </argument> <description> - Constructs the transform from a given angle (in radians) and position. + Constructs the transform from a 3D [Transform]. </description> </method> <method name="affine_inverse"> @@ -98,9 +98,9 @@ <method name="interpolate_with"> <return type="Transform2D"> </return> - <argument index="0" name="transform" type="Transform2D"> + <argument index="0" name="xform" type="Transform2D"> </argument> - <argument index="1" name="weight" type="float"> + <argument index="1" name="t" type="float"> </argument> <description> Returns a transform interpolated between this transform and another by a given weight (on the range of 0.0 to 1.0). @@ -116,7 +116,7 @@ <method name="is_equal_approx"> <return type="bool"> </return> - <argument index="0" name="transform" type="Transform2D"> + <argument index="0" name="xform" type="Transform2D"> </argument> <description> Returns [code]true[/code] if this transform and [code]transform[/code] are approximately equal, by calling [code]is_equal_approx[/code] on each component. @@ -157,24 +157,6 @@ Unlike [method rotated] and [method scaled], this does not use matrix multiplication. </description> </method> - <method name="xform"> - <return type="Variant"> - </return> - <argument index="0" name="v" type="Variant"> - </argument> - <description> - Transforms the given [Vector2], [Rect2], or [PackedVector2Array] by this transform. - </description> - </method> - <method name="xform_inv"> - <return type="Variant"> - </return> - <argument index="0" name="v" type="Variant"> - </argument> - <description> - Inverse-transforms the given [Vector2], [Rect2], or [PackedVector2Array] by this transform. - </description> - </method> </methods> <members> <member name="origin" type="Vector2" setter="" getter="" default="Vector2( 0, 0 )"> diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml index 025d6474ee..231e0ed06a 100644 --- a/doc/classes/Vector2.xml +++ b/doc/classes/Vector2.xml @@ -177,7 +177,7 @@ <method name="is_equal_approx"> <return type="bool"> </return> - <argument index="0" name="v" type="Vector2"> + <argument index="0" name="to" type="Vector2"> </argument> <description> Returns [code]true[/code] if this vector and [code]v[/code] are approximately equal, by running [method @GDScript.is_equal_approx] on each component. @@ -208,7 +208,7 @@ <method name="lerp"> <return type="Vector2"> </return> - <argument index="0" name="b" type="Vector2"> + <argument index="0" name="with" type="Vector2"> </argument> <argument index="1" name="t" type="float"> </argument> @@ -296,7 +296,7 @@ <method name="slerp"> <return type="Vector2"> </return> - <argument index="0" name="b" type="Vector2"> + <argument index="0" name="with" type="Vector2"> </argument> <argument index="1" name="t" type="float"> </argument> diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml index b26fe09e91..7e47f768b4 100644 --- a/doc/classes/Vector3.xml +++ b/doc/classes/Vector3.xml @@ -74,7 +74,7 @@ <method name="cross"> <return type="Vector3"> </return> - <argument index="0" name="b" type="Vector3"> + <argument index="0" name="with" type="Vector3"> </argument> <description> Returns the cross product of this vector and [code]b[/code]. @@ -126,7 +126,7 @@ <method name="dot"> <return type="float"> </return> - <argument index="0" name="b" type="Vector3"> + <argument index="0" name="with" type="Vector3"> </argument> <description> Returns the dot product of this vector and [code]b[/code]. This can be used to compare the angle between two vectors. For example, this can be used to determine whether an enemy is facing the player. @@ -152,7 +152,7 @@ <method name="is_equal_approx"> <return type="bool"> </return> - <argument index="0" name="v" type="Vector3"> + <argument index="0" name="to" type="Vector3"> </argument> <description> Returns [code]true[/code] if this vector and [code]v[/code] are approximately equal, by running [method @GDScript.is_equal_approx] on each component. @@ -226,7 +226,7 @@ <method name="outer"> <return type="Basis"> </return> - <argument index="0" name="b" type="Vector3"> + <argument index="0" name="with" type="Vector3"> </argument> <description> Returns the outer product with [code]b[/code]. @@ -271,7 +271,7 @@ <method name="rotated"> <return type="Vector3"> </return> - <argument index="0" name="axis" type="Vector3"> + <argument index="0" name="by_axis" type="Vector3"> </argument> <argument index="1" name="phi" type="float"> </argument> diff --git a/doc/classes/Vector3i.xml b/doc/classes/Vector3i.xml index f977b81ce7..45e237fb23 100644 --- a/doc/classes/Vector3i.xml +++ b/doc/classes/Vector3i.xml @@ -36,6 +36,12 @@ Constructs a new [Vector3i] from [Vector3]. The floating point coordinates will be truncated. </description> </method> + <method name="abs"> + <return type="Vector3i"> + </return> + <description> + </description> + </method> <method name="max_axis"> <return type="int"> </return> diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml index 84974874de..85dc5e8fd8 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -250,9 +250,15 @@ The shadow atlas' resolution (used for omni and spot lights). The value will be rounded up to the nearest power of 2. [b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-created viewports default to a value of 0, this value must be set above 0 manually. </member> + <member name="snap_2d_transforms_to_pixel" type="bool" setter="set_snap_2d_transforms_to_pixel" getter="is_snap_2d_transforms_to_pixel_enabled" default="false"> + </member> + <member name="snap_2d_vertices_to_pixel" type="bool" setter="set_snap_2d_vertices_to_pixel" getter="is_snap_2d_vertices_to_pixel_enabled" default="false"> + </member> <member name="transparent_bg" type="bool" setter="set_transparent_background" getter="has_transparent_background" default="false"> If [code]true[/code], the viewport should render its background as transparent. </member> + <member name="use_debanding" type="bool" setter="set_use_debanding" getter="is_using_debanding" default="false"> + </member> <member name="world_2d" type="World2D" setter="set_world_2d" getter="get_world_2d"> The custom [World2D] which can be used as 2D environment source. </member> diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 5038941784..7002ffa109 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -351,8 +351,8 @@ void Node3DEditorViewport::_update_camera(float p_interp_delta) { update_transform_gizmo_view(); rotation_control->update(); + spatial_editor->update_grid(); } - spatial_editor->update_grid(); } Transform Node3DEditorViewport::to_camera_transform(const Cursor &p_cursor) const { diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 5250115608..ab4edb04b9 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -2279,10 +2279,12 @@ void GDScriptAnalyzer::reduce_identifier(GDScriptParser::IdentifierNode *p_ident StringName name = p_identifier->name; p_identifier->source = GDScriptParser::IdentifierNode::UNDEFINED_SOURCE; - // Check globals. - if (GDScriptParser::get_builtin_type(name) < Variant::VARIANT_MAX) { + // Check globals. We make an exception for Variant::OBJECT because it's the base class for + // non-builtin types so we allow doing e.g. Object.new() + Variant::Type builtin_type = GDScriptParser::get_builtin_type(name); + if (builtin_type != Variant::OBJECT && builtin_type < Variant::VARIANT_MAX) { if (can_be_builtin) { - p_identifier->set_datatype(make_builtin_meta_type(GDScriptParser::get_builtin_type(name))); + p_identifier->set_datatype(make_builtin_meta_type(builtin_type)); return; } else { push_error(R"(Builtin type cannot be used as a name on its own.)", p_identifier); diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index e59f99fc56..1da0e7b4c6 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -1093,6 +1093,13 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE_BREAK; } } + } else if (methodstr == "call_recursive" && basestr == "TreeItem") { + if (argc >= 1) { + methodstr = String(*argptrs[0]) + " (via TreeItem.call_recursive)"; + if (err.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) { + err.argument += 1; + } + } } err_text = _get_call_error(err, "function '" + methodstr + "' in base '" + basestr + "'", (const Variant **)argptrs); OPCODE_BREAK; diff --git a/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml b/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml index f13d449064..1c22070ab1 100644 --- a/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml +++ b/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml @@ -31,5 +31,7 @@ </constant> <constant name="CALL_MODE_INSTANCE" value="2" enum="CallMode"> </constant> + <constant name="CALL_MODE_BASIC_TYPE" value="3" enum="CallMode"> + </constant> </constants> </class> diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py index 5ebabdd3dc..ab453c353f 100644 --- a/platform/iphone/detect.py +++ b/platform/iphone/detect.py @@ -119,7 +119,7 @@ def configure(env): arch_flag = "i386" if env["arch"] == "x86" else env["arch"] env.Append( CCFLAGS=( - "-arch " + "-fobjc-arc -arch " + arch_flag + " -fobjc-abi-version=2 -fobjc-legacy-dispatch -fmessage-length=0 -fpascal-strings -fblocks" " -fasm-blocks -isysroot $IPHONESDK -mios-simulator-version-min=13.0" diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index 4fc0882fdd..8e425b62da 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -33,54 +33,6 @@ #include "core/engine.h" #include "servers/rendering_server.h" -#ifdef TOOLS_ENABLED -Dictionary Light2D::_edit_get_state() const { - Dictionary state = Node2D::_edit_get_state(); - state["offset"] = get_texture_offset(); - return state; -} - -void Light2D::_edit_set_state(const Dictionary &p_state) { - Node2D::_edit_set_state(p_state); - set_texture_offset(p_state["offset"]); -} - -void Light2D::_edit_set_pivot(const Point2 &p_pivot) { - set_position(get_transform().xform(p_pivot)); - set_texture_offset(get_texture_offset() - p_pivot); -} - -Point2 Light2D::_edit_get_pivot() const { - return Vector2(); -} - -bool Light2D::_edit_use_pivot() const { - return true; -} - -Rect2 Light2D::_edit_get_rect() const { - if (texture.is_null()) { - return Rect2(); - } - - Size2 s = texture->get_size() * _scale; - return Rect2(texture_offset - s / 2.0, s); -} - -bool Light2D::_edit_use_rect() const { - return !texture.is_null(); -} -#endif - -Rect2 Light2D::get_anchorable_rect() const { - if (texture.is_null()) { - return Rect2(); - } - - Size2 s = texture->get_size() * _scale; - return Rect2(texture_offset - s / 2.0, s); -} - void Light2D::_update_light_visibility() { if (!is_inside_tree()) { return; @@ -123,32 +75,6 @@ bool Light2D::is_editor_only() const { return editor_only; } -void Light2D::set_texture(const Ref<Texture2D> &p_texture) { - texture = p_texture; - if (texture.is_valid()) { - RS::get_singleton()->canvas_light_set_texture(canvas_light, texture->get_rid()); - } else { - RS::get_singleton()->canvas_light_set_texture(canvas_light, RID()); - } - - update_configuration_warning(); -} - -Ref<Texture2D> Light2D::get_texture() const { - return texture; -} - -void Light2D::set_texture_offset(const Vector2 &p_offset) { - texture_offset = p_offset; - RS::get_singleton()->canvas_light_set_texture_offset(canvas_light, texture_offset); - item_rect_changed(); - _change_notify("offset"); -} - -Vector2 Light2D::get_texture_offset() const { - return texture_offset; -} - void Light2D::set_color(const Color &p_color) { color = p_color; RS::get_singleton()->canvas_light_set_color(canvas_light, color); @@ -176,20 +102,6 @@ float Light2D::get_energy() const { return energy; } -void Light2D::set_texture_scale(float p_scale) { - _scale = p_scale; - // Avoid having 0 scale values, can lead to errors in physics and rendering. - if (_scale == 0) { - _scale = CMP_EPSILON; - } - RS::get_singleton()->canvas_light_set_scale(canvas_light, _scale); - item_rect_changed(); -} - -float Light2D::get_texture_scale() const { - return _scale; -} - void Light2D::set_z_range_min(int p_min_z) { z_min = p_min_z; RS::get_singleton()->canvas_light_set_z_range(canvas_light, z_min, z_max); @@ -244,15 +156,6 @@ int Light2D::get_item_shadow_cull_mask() const { return item_shadow_mask; } -void Light2D::set_mode(Mode p_mode) { - mode = p_mode; - RS::get_singleton()->canvas_light_set_mode(canvas_light, RS::CanvasLightMode(p_mode)); -} - -Light2D::Mode Light2D::get_mode() const { - return mode; -} - void Light2D::set_shadow_enabled(bool p_enabled) { shadow = p_enabled; RS::get_singleton()->canvas_light_set_shadow_enabled(canvas_light, shadow); @@ -281,6 +184,15 @@ Color Light2D::get_shadow_color() const { return shadow_color; } +void Light2D::set_blend_mode(BlendMode p_mode) { + blend_mode = p_mode; + RS::get_singleton()->canvas_light_set_blend_mode(_get_light(), RS::CanvasLightBlendMode(p_mode)); +} + +Light2D::BlendMode Light2D::get_blend_mode() const { + return blend_mode; +} + void Light2D::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { RS::get_singleton()->canvas_light_attach_to_canvas(canvas_light, get_canvas()); @@ -300,19 +212,6 @@ void Light2D::_notification(int p_what) { } } -String Light2D::get_configuration_warning() const { - String warning = Node2D::get_configuration_warning(); - - if (!texture.is_valid()) { - if (!warning.empty()) { - warning += "\n\n"; - } - warning += TTR("A texture with the shape of the light must be supplied to the \"Texture\" property."); - } - - return warning; -} - void Light2D::set_shadow_smooth(float p_amount) { shadow_smooth = p_amount; RS::get_singleton()->canvas_light_set_shadow_smooth(canvas_light, shadow_smooth); @@ -329,24 +228,12 @@ void Light2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_editor_only", "editor_only"), &Light2D::set_editor_only); ClassDB::bind_method(D_METHOD("is_editor_only"), &Light2D::is_editor_only); - ClassDB::bind_method(D_METHOD("set_texture", "texture"), &Light2D::set_texture); - ClassDB::bind_method(D_METHOD("get_texture"), &Light2D::get_texture); - - ClassDB::bind_method(D_METHOD("set_texture_offset", "texture_offset"), &Light2D::set_texture_offset); - ClassDB::bind_method(D_METHOD("get_texture_offset"), &Light2D::get_texture_offset); - ClassDB::bind_method(D_METHOD("set_color", "color"), &Light2D::set_color); ClassDB::bind_method(D_METHOD("get_color"), &Light2D::get_color); - ClassDB::bind_method(D_METHOD("set_height", "height"), &Light2D::set_height); - ClassDB::bind_method(D_METHOD("get_height"), &Light2D::get_height); - ClassDB::bind_method(D_METHOD("set_energy", "energy"), &Light2D::set_energy); ClassDB::bind_method(D_METHOD("get_energy"), &Light2D::get_energy); - ClassDB::bind_method(D_METHOD("set_texture_scale", "texture_scale"), &Light2D::set_texture_scale); - ClassDB::bind_method(D_METHOD("get_texture_scale"), &Light2D::get_texture_scale); - ClassDB::bind_method(D_METHOD("set_z_range_min", "z"), &Light2D::set_z_range_min); ClassDB::bind_method(D_METHOD("get_z_range_min"), &Light2D::get_z_range_min); @@ -365,9 +252,6 @@ void Light2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_item_shadow_cull_mask", "item_shadow_cull_mask"), &Light2D::set_item_shadow_cull_mask); ClassDB::bind_method(D_METHOD("get_item_shadow_cull_mask"), &Light2D::get_item_shadow_cull_mask); - ClassDB::bind_method(D_METHOD("set_mode", "mode"), &Light2D::set_mode); - ClassDB::bind_method(D_METHOD("get_mode"), &Light2D::get_mode); - ClassDB::bind_method(D_METHOD("set_shadow_enabled", "enabled"), &Light2D::set_shadow_enabled); ClassDB::bind_method(D_METHOD("is_shadow_enabled"), &Light2D::is_shadow_enabled); @@ -380,16 +264,18 @@ void Light2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shadow_color", "shadow_color"), &Light2D::set_shadow_color); ClassDB::bind_method(D_METHOD("get_shadow_color"), &Light2D::get_shadow_color); + ClassDB::bind_method(D_METHOD("set_blend_mode", "mode"), &Light2D::set_blend_mode); + ClassDB::bind_method(D_METHOD("get_blend_mode"), &Light2D::get_blend_mode); + + ClassDB::bind_method(D_METHOD("set_height", "height"), &Light2D::set_height); + ClassDB::bind_method(D_METHOD("get_height"), &Light2D::get_height); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "is_editor_only"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_texture_offset", "get_texture_offset"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texture_scale", PROPERTY_HINT_RANGE, "0.01,50,0.01"), "set_texture_scale", "get_texture_scale"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_energy", "get_energy"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Add,Sub,Mix,Mask"), "set_mode", "get_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Add,Sub,Mix"), "set_blend_mode", "get_blend_mode"); ADD_GROUP("Range", "range_"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "range_height", PROPERTY_HINT_RANGE, "-2048,2048,0.1,or_lesser,or_greater"), "set_height", "get_height"); ADD_PROPERTY(PropertyInfo(Variant::INT, "range_z_min", PROPERTY_HINT_RANGE, itos(RS::CANVAS_ITEM_Z_MIN) + "," + itos(RS::CANVAS_ITEM_Z_MAX) + ",1"), "set_z_range_min", "get_z_range_min"); ADD_PROPERTY(PropertyInfo(Variant::INT, "range_z_max", PROPERTY_HINT_RANGE, itos(RS::CANVAS_ITEM_Z_MIN) + "," + itos(RS::CANVAS_ITEM_Z_MAX) + ",1"), "set_z_range_max", "get_z_range_max"); ADD_PROPERTY(PropertyInfo(Variant::INT, "range_layer_min", PROPERTY_HINT_RANGE, "-512,512,1"), "set_layer_range_min", "get_layer_range_min"); @@ -403,14 +289,13 @@ void Light2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "shadow_filter_smooth", PROPERTY_HINT_RANGE, "0,64,0.1"), "set_shadow_smooth", "get_shadow_smooth"); ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_item_cull_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_item_shadow_cull_mask", "get_item_shadow_cull_mask"); - BIND_ENUM_CONSTANT(MODE_ADD); - BIND_ENUM_CONSTANT(MODE_SUB); - BIND_ENUM_CONSTANT(MODE_MIX); - BIND_ENUM_CONSTANT(MODE_MASK); - BIND_ENUM_CONSTANT(SHADOW_FILTER_NONE); BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF5); BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF13); + + BIND_ENUM_CONSTANT(BLEND_MODE_ADD); + BIND_ENUM_CONSTANT(BLEND_MODE_SUB); + BIND_ENUM_CONSTANT(BLEND_MODE_MIX); } Light2D::Light2D() { @@ -420,22 +305,168 @@ Light2D::Light2D() { shadow = false; color = Color(1, 1, 1); height = 0; - _scale = 1.0; z_min = -1024; z_max = 1024; layer_min = 0; layer_max = 0; item_mask = 1; item_shadow_mask = 1; - mode = MODE_ADD; energy = 1.0; shadow_color = Color(0, 0, 0, 0); shadow_filter = SHADOW_FILTER_NONE; shadow_smooth = 0; - + blend_mode = BLEND_MODE_ADD; set_notify_transform(true); } Light2D::~Light2D() { RenderingServer::get_singleton()->free(canvas_light); } + +////////////////////////////// + +#ifdef TOOLS_ENABLED + +Dictionary PointLight2D::_edit_get_state() const { + Dictionary state = Node2D::_edit_get_state(); + state["offset"] = get_texture_offset(); + return state; +} + +void PointLight2D::_edit_set_state(const Dictionary &p_state) { + Node2D::_edit_set_state(p_state); + set_texture_offset(p_state["offset"]); +} + +void PointLight2D::_edit_set_pivot(const Point2 &p_pivot) { + set_position(get_transform().xform(p_pivot)); + set_texture_offset(get_texture_offset() - p_pivot); +} + +Point2 PointLight2D::_edit_get_pivot() const { + return Vector2(); +} + +bool PointLight2D::_edit_use_pivot() const { + return true; +} + +Rect2 PointLight2D::_edit_get_rect() const { + if (texture.is_null()) { + return Rect2(); + } + + Size2 s = texture->get_size() * _scale; + return Rect2(texture_offset - s / 2.0, s); +} + +bool PointLight2D::_edit_use_rect() const { + return !texture.is_null(); +} +#endif + +Rect2 PointLight2D::get_anchorable_rect() const { + if (texture.is_null()) { + return Rect2(); + } + + Size2 s = texture->get_size() * _scale; + return Rect2(texture_offset - s / 2.0, s); +} + +void PointLight2D::set_texture(const Ref<Texture2D> &p_texture) { + texture = p_texture; + if (texture.is_valid()) { + RS::get_singleton()->canvas_light_set_texture(_get_light(), texture->get_rid()); + } else { + RS::get_singleton()->canvas_light_set_texture(_get_light(), RID()); + } + + update_configuration_warning(); +} + +Ref<Texture2D> PointLight2D::get_texture() const { + return texture; +} + +void PointLight2D::set_texture_offset(const Vector2 &p_offset) { + texture_offset = p_offset; + RS::get_singleton()->canvas_light_set_texture_offset(_get_light(), texture_offset); + item_rect_changed(); + _change_notify("offset"); +} + +Vector2 PointLight2D::get_texture_offset() const { + return texture_offset; +} + +String PointLight2D::get_configuration_warning() const { + String warning = Node2D::get_configuration_warning(); + + if (!texture.is_valid()) { + if (!warning.empty()) { + warning += "\n\n"; + } + warning += TTR("A texture with the shape of the light must be supplied to the \"Texture\" property."); + } + + return warning; +} + +void PointLight2D::set_texture_scale(float p_scale) { + _scale = p_scale; + // Avoid having 0 scale values, can lead to errors in physics and rendering. + if (_scale == 0) { + _scale = CMP_EPSILON; + } + RS::get_singleton()->canvas_light_set_texture_scale(_get_light(), _scale); + item_rect_changed(); +} + +float PointLight2D::get_texture_scale() const { + return _scale; +} + +void PointLight2D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_texture", "texture"), &PointLight2D::set_texture); + ClassDB::bind_method(D_METHOD("get_texture"), &PointLight2D::get_texture); + + ClassDB::bind_method(D_METHOD("set_texture_offset", "texture_offset"), &PointLight2D::set_texture_offset); + ClassDB::bind_method(D_METHOD("get_texture_offset"), &PointLight2D::get_texture_offset); + + ClassDB::bind_method(D_METHOD("set_texture_scale", "texture_scale"), &PointLight2D::set_texture_scale); + ClassDB::bind_method(D_METHOD("get_texture_scale"), &PointLight2D::get_texture_scale); + + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_texture_offset", "get_texture_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texture_scale", PROPERTY_HINT_RANGE, "0.01,50,0.01"), "set_texture_scale", "get_texture_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0,1024,1,or_greater"), "set_height", "get_height"); +} + +PointLight2D::PointLight2D() { + RS::get_singleton()->canvas_light_set_mode(_get_light(), RS::CANVAS_LIGHT_MODE_POINT); +} + +////////// + +void DirectionalLight2D::set_max_distance(float p_distance) { + max_distance = p_distance; + RS::get_singleton()->canvas_light_set_directional_distance(_get_light(), max_distance); +} + +float DirectionalLight2D::get_max_distance() const { + return max_distance; +} + +void DirectionalLight2D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_max_distance", "pixels"), &DirectionalLight2D::set_max_distance); + ClassDB::bind_method(D_METHOD("get_max_distance"), &DirectionalLight2D::get_max_distance); + + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_height", "get_height"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_distance", PROPERTY_HINT_RANGE, "0,16384.0,1.0,or_greater"), "set_max_distance", "get_max_distance"); +} + +DirectionalLight2D::DirectionalLight2D() { + RS::get_singleton()->canvas_light_set_mode(_get_light(), RS::CANVAS_LIGHT_MODE_DIRECTIONAL); + set_max_distance(max_distance); // Update RenderingServer. +} diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h index 095cb05635..7dfeddc8e5 100644 --- a/scene/2d/light_2d.h +++ b/scene/2d/light_2d.h @@ -37,13 +37,6 @@ class Light2D : public Node2D { GDCLASS(Light2D, Node2D); public: - enum Mode { - MODE_ADD, - MODE_SUB, - MODE_MIX, - MODE_MASK, - }; - enum ShadowFilter { SHADOW_FILTER_NONE, SHADOW_FILTER_PCF5, @@ -51,6 +44,12 @@ public: SHADOW_FILTER_MAX }; + enum BlendMode { + BLEND_MODE_ADD, + BLEND_MODE_SUB, + BLEND_MODE_MIX, + }; + private: RID canvas_light; bool enabled; @@ -59,7 +58,6 @@ private: Color color; Color shadow_color; float height; - float _scale; float energy; int z_min; int z_max; @@ -68,43 +66,25 @@ private: int item_mask; int item_shadow_mask; float shadow_smooth; - Mode mode; Ref<Texture2D> texture; Vector2 texture_offset; ShadowFilter shadow_filter; + BlendMode blend_mode; void _update_light_visibility(); protected: + _FORCE_INLINE_ RID _get_light() const { return canvas_light; } void _notification(int p_what); static void _bind_methods(); public: -#ifdef TOOLS_ENABLED - virtual Dictionary _edit_get_state() const override; - virtual void _edit_set_state(const Dictionary &p_state) override; - - virtual void _edit_set_pivot(const Point2 &p_pivot) override; - virtual Point2 _edit_get_pivot() const override; - virtual bool _edit_use_pivot() const override; - virtual Rect2 _edit_get_rect() const override; - virtual bool _edit_use_rect() const override; -#endif - - virtual Rect2 get_anchorable_rect() const override; - void set_enabled(bool p_enabled); bool is_enabled() const; void set_editor_only(bool p_editor_only); bool is_editor_only() const; - void set_texture(const Ref<Texture2D> &p_texture); - Ref<Texture2D> get_texture() const; - - void set_texture_offset(const Vector2 &p_offset); - Vector2 get_texture_offset() const; - void set_color(const Color &p_color); Color get_color() const; @@ -114,9 +94,6 @@ public: void set_energy(float p_energy); float get_energy() const; - void set_texture_scale(float p_scale); - float get_texture_scale() const; - void set_z_range_min(int p_min_z); int get_z_range_min() const; @@ -135,9 +112,6 @@ public: void set_item_shadow_cull_mask(int p_mask); int get_item_shadow_cull_mask() const; - void set_mode(Mode p_mode); - Mode get_mode() const; - void set_shadow_enabled(bool p_enabled); bool is_shadow_enabled() const; @@ -150,13 +124,68 @@ public: void set_shadow_smooth(float p_amount); float get_shadow_smooth() const; - String get_configuration_warning() const override; + void set_blend_mode(BlendMode p_mode); + BlendMode get_blend_mode() const; Light2D(); ~Light2D(); }; -VARIANT_ENUM_CAST(Light2D::Mode); VARIANT_ENUM_CAST(Light2D::ShadowFilter); +VARIANT_ENUM_CAST(Light2D::BlendMode); + +class PointLight2D : public Light2D { + GDCLASS(PointLight2D, Light2D); + +private: + float _scale = 1.0; + Ref<Texture2D> texture; + Vector2 texture_offset; + +protected: + static void _bind_methods(); + +public: +#ifdef TOOLS_ENABLED + virtual Dictionary _edit_get_state() const override; + virtual void _edit_set_state(const Dictionary &p_state) override; + + virtual void _edit_set_pivot(const Point2 &p_pivot) override; + virtual Point2 _edit_get_pivot() const override; + virtual bool _edit_use_pivot() const override; + virtual Rect2 _edit_get_rect() const override; + virtual bool _edit_use_rect() const override; +#endif + + virtual Rect2 get_anchorable_rect() const override; + + void set_texture(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_texture() const; + + void set_texture_offset(const Vector2 &p_offset); + Vector2 get_texture_offset() const; + + void set_texture_scale(float p_scale); + float get_texture_scale() const; + + String get_configuration_warning() const override; + + PointLight2D(); +}; + +class DirectionalLight2D : public Light2D { + GDCLASS(DirectionalLight2D, Light2D); + + float max_distance = 10000.0; + +protected: + static void _bind_methods(); + +public: + void set_max_distance(float p_distance); + float get_max_distance() const; + + DirectionalLight2D(); +}; #endif // LIGHT_2D_H diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 476dccab7e..cb35519da1 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -2738,7 +2738,9 @@ void Control::_bind_methods() { BIND_VMETHOD(MethodInfo(Variant::BOOL, "can_drop_data", PropertyInfo(Variant::VECTOR2, "position"), PropertyInfo(Variant::NIL, "data"))); BIND_VMETHOD(MethodInfo("drop_data", PropertyInfo(Variant::VECTOR2, "position"), PropertyInfo(Variant::NIL, "data"))); - BIND_VMETHOD(MethodInfo(Variant::OBJECT, "_make_custom_tooltip", PropertyInfo(Variant::STRING, "for_text"))); + BIND_VMETHOD(MethodInfo( + PropertyInfo(Variant::OBJECT, "control", PROPERTY_HINT_RESOURCE_TYPE, "Control"), + "_make_custom_tooltip", PropertyInfo(Variant::STRING, "for_text"))); BIND_VMETHOD(MethodInfo(Variant::BOOL, "_clips_input")); ADD_GROUP("Anchor", "anchor_"); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index b9a913edb4..d512f1809c 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -161,6 +161,11 @@ ViewportTexture::~ViewportTexture() { ///////////////////////////////////// +// Aliases used to provide custom styles to tooltips in the default +// theme and editor theme. +// TooltipPanel is also used for custom tooltips, while TooltipLabel +// is only relevant for default tooltips. + class TooltipPanel : public PopupPanel { GDCLASS(TooltipPanel, PopupPanel); @@ -175,6 +180,8 @@ public: TooltipLabel() {} }; +///////////////////////////////////// + Viewport::GUI::GUI() { embed_subwindows_hint = false; embedding_subwindows = false; @@ -188,7 +195,7 @@ Viewport::GUI::GUI() { mouse_over = nullptr; drag_mouse_over = nullptr; - tooltip = nullptr; + tooltip_control = nullptr; tooltip_popup = nullptr; tooltip_label = nullptr; } @@ -814,7 +821,14 @@ void Viewport::_notification(int p_what) { } } break; - case NOTIFICATION_WM_MOUSE_EXIT: + case NOTIFICATION_WM_MOUSE_EXIT: { + _drop_physics_mouseover(); + + // Unlike on loss of focus (NOTIFICATION_WM_WINDOW_FOCUS_OUT), do not + // drop the gui mouseover here, as a scrollbar may be dragged while the + // mouse is outside the window (without the window having lost focus). + // See bug #39634 + } break; case NOTIFICATION_WM_WINDOW_FOCUS_OUT: { _drop_physics_mouseover(); @@ -1465,7 +1479,7 @@ void Viewport::_gui_sort_roots() { } void Viewport::_gui_cancel_tooltip() { - gui.tooltip = nullptr; + gui.tooltip_control = nullptr; gui.tooltip_timer = -1; if (gui.tooltip_popup) { gui.tooltip_popup->queue_delete(); @@ -1474,21 +1488,23 @@ void Viewport::_gui_cancel_tooltip() { } } -String Viewport::_gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Control **r_which) { +String Viewport::_gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Control **r_tooltip_owner) { Vector2 pos = p_pos; String tooltip; while (p_control) { tooltip = p_control->get_tooltip(pos); - if (r_which) { - *r_which = p_control; + if (r_tooltip_owner) { + *r_tooltip_owner = p_control; } - if (tooltip != String()) { + // If we found a tooltip, we stop here. + if (!tooltip.empty()) { break; } - pos = p_control->get_transform().xform(pos); + + // Otherwise, we check parent controls unless some conditions prevent it. if (p_control->data.mouse_filter == Control::MOUSE_FILTER_STOP) { break; @@ -1497,6 +1513,9 @@ String Viewport::_gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Cont break; } + // Transform cursor pos for parent control. + pos = p_control->get_transform().xform(pos); + p_control = p_control->get_parent_control(); } @@ -1504,34 +1523,40 @@ String Viewport::_gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Cont } void Viewport::_gui_show_tooltip() { - if (!gui.tooltip) { + if (!gui.tooltip_control) { return; } - Control *which = nullptr; - String tooltip = _gui_get_tooltip(gui.tooltip, gui.tooltip->get_global_transform().xform_inv(gui.last_mouse_pos), &which); - tooltip = tooltip.strip_edges(); - if (tooltip.length() == 0) { - return; // bye + // Get the Control under cursor and the relevant tooltip text, if any. + Control *tooltip_owner = nullptr; + String tooltip_text = _gui_get_tooltip( + gui.tooltip_control, + gui.tooltip_control->get_global_transform().xform_inv(gui.last_mouse_pos), + &tooltip_owner); + tooltip_text.strip_edges(); + if (tooltip_text.empty()) { + return; // Nothing to show. } + // Remove previous popup if we change something. if (gui.tooltip_popup) { memdelete(gui.tooltip_popup); gui.tooltip_popup = nullptr; gui.tooltip_label = nullptr; } - if (!which) { + if (!tooltip_owner) { return; } - Control *rp = which; - - Control *base_tooltip = which->make_custom_tooltip(tooltip); + // Controls can implement `make_custom_tooltip` to provide their own tooltip. + // This should be a Control node which will be added as child to a TooltipPanel. + Control *base_tooltip = tooltip_owner->make_custom_tooltip(tooltip_text); + // If no custom tooltip is given, use a default implementation. if (!base_tooltip) { gui.tooltip_label = memnew(TooltipLabel); - gui.tooltip_label->set_text(tooltip); + gui.tooltip_label->set_text(tooltip_text); base_tooltip = gui.tooltip_label; } @@ -1545,10 +1570,7 @@ void Viewport::_gui_show_tooltip() { gui.tooltip_popup = panel; - rp->add_child(gui.tooltip_popup); - - //if (gui.tooltip) // Avoids crash when rapidly switching controls. - // gui.tooltip_popup->set_scale(gui.tooltip->get_global_transform().get_scale()); + tooltip_owner->add_child(gui.tooltip_popup); Point2 tooltip_offset = ProjectSettings::get_singleton()->get("display/mouse_cursor/tooltip_position_offset"); Rect2 r(gui.tooltip_pos + tooltip_offset, gui.tooltip_popup->get_contents_minimum_size()); @@ -1794,6 +1816,8 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (mb.is_valid()) { gui.key_event_accepted = false; + Control *over = nullptr; + Point2 mpos = mb->get_position(); if (mb->is_pressed()) { Size2 pos = mpos; @@ -1897,8 +1921,6 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { } _gui_cancel_tooltip(); - //gui.tooltip_popup->hide(); - } else { if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == BUTTON_LEFT) { if (gui.drag_mouse_over) { @@ -1948,6 +1970,31 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { gui.drag_data=Variant(); //always clear }*/ + // In case the mouse was released after for example dragging a scrollbar, + // check whether the current control is different from the stored one. If + // it is different, rather than wait for it to be updated the next time the + // mouse is moved, notify the control so that it can e.g. drop the highlight. + // This code is duplicated from the mm.is_valid()-case further below. + if (gui.mouse_focus) { + over = gui.mouse_focus; + } else { + over = _gui_find_control(mpos); + } + + if (gui.mouse_focus_mask == 0 && over != gui.mouse_over) { + if (gui.mouse_over) { + _gui_call_notification(gui.mouse_over, Control::NOTIFICATION_MOUSE_EXIT); + } + + _gui_cancel_tooltip(); + + if (over) { + _gui_call_notification(over, Control::NOTIFICATION_MOUSE_ENTER); + } + } + + gui.mouse_over = over; + set_input_as_handled(); } } @@ -2008,10 +2055,11 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { } } + // These sections of code are reused in the mb.is_valid() case further up + // for the purpose of notifying controls about potential changes in focus + // when the mousebutton is released. if (gui.mouse_focus) { over = gui.mouse_focus; - //recompute focus_inv_xform again here - } else { over = _gui_find_control(mpos); } @@ -2052,8 +2100,8 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { bool is_tooltip_shown = false; if (gui.tooltip_popup) { - if (can_tooltip && gui.tooltip) { - String tooltip = _gui_get_tooltip(over, gui.tooltip->get_global_transform().xform_inv(mpos)); + if (can_tooltip && gui.tooltip_control) { + String tooltip = _gui_get_tooltip(over, gui.tooltip_control->get_global_transform().xform_inv(mpos)); if (tooltip.length() == 0) { _gui_cancel_tooltip(); @@ -2078,14 +2126,12 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { } if (can_tooltip && !is_tooltip_shown) { - gui.tooltip = over; - gui.tooltip_pos = over->get_screen_transform().xform(pos); //(parent_xform * get_transform()).affine_inverse().xform(pos); + gui.tooltip_control = over; + gui.tooltip_pos = over->get_screen_transform().xform(pos); gui.tooltip_timer = gui.tooltip_delay; } } - //pos = gui.focus_inv_xform.xform(pos); - mm->set_position(pos); Control::CursorShape cursor_shape = Control::CURSOR_ARROW; @@ -2436,7 +2482,7 @@ void Viewport::_gui_hide_control(Control *p_control) { if (gui.drag_mouse_over == p_control) { gui.drag_mouse_over = nullptr; } - if (gui.tooltip == p_control) { + if (gui.tooltip_control == p_control) { _gui_cancel_tooltip(); } } @@ -2459,8 +2505,8 @@ void Viewport::_gui_remove_control(Control *p_control) { if (gui.drag_mouse_over == p_control) { gui.drag_mouse_over = nullptr; } - if (gui.tooltip == p_control) { - gui.tooltip = nullptr; + if (gui.tooltip_control == p_control) { + gui.tooltip_control = nullptr; } } @@ -3579,14 +3625,13 @@ Viewport::Viewport() { disable_input = false; - //window tooltip + // Window tooltip. gui.tooltip_timer = -1; - //gui.tooltip_timer->force_parent_owned(); gui.tooltip_delay = GLOBAL_DEF("gui/timers/tooltip_delay_sec", 0.5); ProjectSettings::get_singleton()->set_custom_property_info("gui/timers/tooltip_delay_sec", PropertyInfo(Variant::FLOAT, "gui/timers/tooltip_delay_sec", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater")); // No negative numbers - gui.tooltip = nullptr; + gui.tooltip_control = nullptr; gui.tooltip_label = nullptr; gui.drag_preview = nullptr; gui.drag_attempted = false; diff --git a/scene/main/viewport.h b/scene/main/viewport.h index b6efd7aa4c..8e7f2cecdc 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -323,7 +323,7 @@ private: Control *mouse_over; Control *drag_mouse_over; Vector2 drag_mouse_over_pos; - Control *tooltip; + Control *tooltip_control; Window *tooltip_popup; Label *tooltip_label; Point2 tooltip_pos; @@ -382,7 +382,7 @@ private: void _gui_remove_root_control(List<Control *>::Element *RI); - String _gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Control **r_which = nullptr); + String _gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Control **r_tooltip_owner = nullptr); void _gui_cancel_tooltip(); void _gui_show_tooltip(); diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index f1dcc8e8a5..9d224dc744 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -628,7 +628,9 @@ void register_scene_types() { ClassDB::register_class<Polygon2D>(); ClassDB::register_class<Skeleton2D>(); ClassDB::register_class<Bone2D>(); - ClassDB::register_class<Light2D>(); + ClassDB::register_virtual_class<Light2D>(); + ClassDB::register_class<PointLight2D>(); + ClassDB::register_class<DirectionalLight2D>(); ClassDB::register_class<LightOccluder2D>(); ClassDB::register_class<OccluderPolygon2D>(); ClassDB::register_class<YSort>(); @@ -917,6 +919,7 @@ void register_scene_types() { ClassDB::add_compatibility_class("VisualShaderNodeScalarUniform", "VisualShaderNodeFloatUniform"); ClassDB::add_compatibility_class("World", "World3D"); ClassDB::add_compatibility_class("StreamTexture", "StreamTexture2D"); + ClassDB::add_compatibility_class("Light2D", "PointLight2D"); #endif diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index a5f8cdaf88..5953942c44 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -2637,6 +2637,8 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : orm = p_orm; // Initialize to the same values as the shader shading_mode = SHADING_MODE_PER_PIXEL; + transparency = TRANSPARENCY_DISABLED; + alpha_antialiasing_mode = ALPHA_ANTIALIASING_OFF; set_albedo(Color(1.0, 1.0, 1.0, 1.0)); set_specular(0.5); set_roughness(1.0); diff --git a/servers/rendering/rasterizer.h b/servers/rendering/rasterizer.h index b2b2b4977b..02aa329b07 100644 --- a/servers/rendering/rasterizer.h +++ b/servers/rendering/rasterizer.h @@ -832,7 +832,9 @@ public: int layer_max; int item_mask; int item_shadow_mask; + float directional_distance; RS::CanvasLightMode mode; + RS::CanvasLightBlendMode blend_mode; RID texture; Vector2 texture_offset; RID canvas; @@ -854,7 +856,7 @@ public: Light *shadows_next_ptr; Light *filter_next_ptr; Light *next_ptr; - Light *mask_next_ptr; + Light *directional_next_ptr; RID light_internal; uint64_t version; @@ -875,16 +877,18 @@ public: scale = 1.0; energy = 1.0; item_shadow_mask = 1; - mode = RS::CANVAS_LIGHT_MODE_ADD; + mode = RS::CANVAS_LIGHT_MODE_POINT; + blend_mode = RS::CANVAS_LIGHT_BLEND_MODE_ADD; // texture_cache = nullptr; next_ptr = nullptr; - mask_next_ptr = nullptr; + directional_next_ptr = nullptr; filter_next_ptr = nullptr; use_shadow = false; shadow_buffer_size = 2048; shadow_filter = RS::CANVAS_LIGHT_FILTER_NONE; shadow_smooth = 0.0; render_index_cache = -1; + directional_distance = 10000.0; } }; @@ -1322,7 +1326,7 @@ public: } }; - virtual void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel) = 0; + virtual void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel) = 0; virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) = 0; struct LightOccluderInstance { @@ -1350,6 +1354,7 @@ public: virtual void light_set_texture(RID p_rid, RID p_texture) = 0; virtual void light_set_use_shadow(RID p_rid, bool p_enable) = 0; virtual void light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) = 0; + virtual void light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) = 0; virtual RID occluder_polygon_create() = 0; virtual void occluder_polygon_set_shape_as_lines(RID p_occluder, const Vector<Vector2> &p_lines) = 0; diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp index da30291353..b33940b22c 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp @@ -416,10 +416,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ light_count++; - if (light->mode == RS::CANVAS_LIGHT_MODE_MASK) { - base_flags |= FLAGS_USING_LIGHT_MASK; - } - if (light_count == MAX_LIGHTS_PER_ITEM) { break; } @@ -430,7 +426,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ base_flags |= light_count << FLAGS_LIGHT_COUNT_SHIFT; } - light_mode = light_count > 0 ? PIPELINE_LIGHT_MODE_ENABLED : PIPELINE_LIGHT_MODE_DISABLED; + light_mode = (light_count > 0 || using_directional_lights) ? PIPELINE_LIGHT_MODE_ENABLED : PIPELINE_LIGHT_MODE_DISABLED; PipelineVariants *pipeline_variants = p_pipeline_variants; @@ -1194,51 +1190,83 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count, RD::get_singleton()->draw_list_end(); } -void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel) { +void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_light_list, const Transform2D &p_canvas_transform, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel) { int item_count = 0; //setup canvas state uniforms if needed Transform2D canvas_transform_inverse = p_canvas_transform.affine_inverse(); + //setup directional lights if exist + + uint32_t light_count = 0; + uint32_t directional_light_count = 0; { - //update canvas state uniform buffer - State::Buffer state_buffer; + Light *l = p_directional_light_list; + uint32_t index = 0; - Size2i ssize = storage->render_target_get_size(p_to_render_target); + while (l) { + if (index == state.max_lights_per_render) { + l->render_index_cache = -1; + l = l->next_ptr; + continue; + } - Transform screen_transform; - screen_transform.translate(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f); - screen_transform.scale(Vector3(2.0f / ssize.width, 2.0f / ssize.height, 1.0f)); - _update_transform_to_mat4(screen_transform, state_buffer.screen_transform); - _update_transform_2d_to_mat4(p_canvas_transform, state_buffer.canvas_transform); + CanvasLight *clight = canvas_light_owner.getornull(l->light_internal); + if (!clight) { //unused or invalid texture + l->render_index_cache = -1; + l = l->next_ptr; + ERR_CONTINUE(!clight); + } - Transform2D normal_transform = p_canvas_transform; - normal_transform.elements[0].normalize(); - normal_transform.elements[1].normalize(); - normal_transform.elements[2] = Vector2(); - _update_transform_2d_to_mat4(normal_transform, state_buffer.canvas_normal_transform); + Vector2 canvas_light_dir = l->xform_cache.elements[1].normalized(); - state_buffer.canvas_modulate[0] = p_modulate.r; - state_buffer.canvas_modulate[1] = p_modulate.g; - state_buffer.canvas_modulate[2] = p_modulate.b; - state_buffer.canvas_modulate[3] = p_modulate.a; + state.light_uniforms[index].position[0] = -canvas_light_dir.x; + state.light_uniforms[index].position[1] = -canvas_light_dir.y; - Size2 render_target_size = storage->render_target_get_size(p_to_render_target); - state_buffer.screen_pixel_size[0] = 1.0 / render_target_size.x; - state_buffer.screen_pixel_size[1] = 1.0 / render_target_size.y; + _update_transform_2d_to_mat2x4(clight->shadow.directional_xform, state.light_uniforms[index].shadow_matrix); - state_buffer.time = state.time; - state_buffer.use_pixel_snap = p_snap_2d_vertices_to_pixel; + state.light_uniforms[index].height = l->height; //0..1 here - RD::get_singleton()->buffer_update(state.canvas_state_buffer, 0, sizeof(State::Buffer), &state_buffer, true); + for (int i = 0; i < 4; i++) { + state.light_uniforms[index].shadow_color[i] = uint8_t(CLAMP(int32_t(l->shadow_color[i] * 255.0), 0, 255)); + state.light_uniforms[index].color[i] = l->color[i]; + } + + state.light_uniforms[index].color[3] = l->energy; //use alpha for energy, so base color can go separate + + if (state.shadow_fb.is_valid()) { + state.light_uniforms[index].shadow_pixel_size = (1.0 / state.shadow_texture_size) * (1.0 + l->shadow_smooth); + state.light_uniforms[index].shadow_z_far_inv = 1.0 / clight->shadow.z_far; + state.light_uniforms[index].shadow_y_ofs = clight->shadow.y_offset; + } else { + state.light_uniforms[index].shadow_pixel_size = 1.0; + state.light_uniforms[index].shadow_z_far_inv = 1.0; + state.light_uniforms[index].shadow_y_ofs = 0; + } + + state.light_uniforms[index].flags = l->blend_mode << LIGHT_FLAGS_BLEND_SHIFT; + state.light_uniforms[index].flags |= l->shadow_filter << LIGHT_FLAGS_FILTER_SHIFT; + if (clight->shadow.enabled) { + state.light_uniforms[index].flags |= LIGHT_FLAGS_HAS_SHADOW; + } + + l->render_index_cache = index; + + index++; + l = l->next_ptr; + } + + light_count = index; + directional_light_count = light_count; + using_directional_lights = directional_light_count > 0; } //setup lights if exist { Light *l = p_light_list; - uint32_t index = 0; + uint32_t index = light_count; while (l) { if (index == state.max_lights_per_render) { @@ -1280,7 +1308,7 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite state.light_uniforms[index].shadow_y_ofs = 0; } - state.light_uniforms[index].flags |= l->mode << LIGHT_FLAGS_BLEND_SHIFT; + state.light_uniforms[index].flags = l->blend_mode << LIGHT_FLAGS_BLEND_SHIFT; state.light_uniforms[index].flags |= l->shadow_filter << LIGHT_FLAGS_FILTER_SHIFT; if (clight->shadow.enabled) { state.light_uniforms[index].flags |= LIGHT_FLAGS_HAS_SHADOW; @@ -1306,9 +1334,46 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite l = l->next_ptr; } - if (index > 0) { - RD::get_singleton()->buffer_update(state.lights_uniform_buffer, 0, sizeof(LightUniform) * index, &state.light_uniforms[0], true); - } + light_count = index; + } + + if (light_count > 0) { + RD::get_singleton()->buffer_update(state.lights_uniform_buffer, 0, sizeof(LightUniform) * light_count, &state.light_uniforms[0], true); + } + + { + //update canvas state uniform buffer + State::Buffer state_buffer; + + Size2i ssize = storage->render_target_get_size(p_to_render_target); + + Transform screen_transform; + screen_transform.translate(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f); + screen_transform.scale(Vector3(2.0f / ssize.width, 2.0f / ssize.height, 1.0f)); + _update_transform_to_mat4(screen_transform, state_buffer.screen_transform); + _update_transform_2d_to_mat4(p_canvas_transform, state_buffer.canvas_transform); + + Transform2D normal_transform = p_canvas_transform; + normal_transform.elements[0].normalize(); + normal_transform.elements[1].normalize(); + normal_transform.elements[2] = Vector2(); + _update_transform_2d_to_mat4(normal_transform, state_buffer.canvas_normal_transform); + + state_buffer.canvas_modulate[0] = p_modulate.r; + state_buffer.canvas_modulate[1] = p_modulate.g; + state_buffer.canvas_modulate[2] = p_modulate.b; + state_buffer.canvas_modulate[3] = p_modulate.a; + + Size2 render_target_size = storage->render_target_get_size(p_to_render_target); + state_buffer.screen_pixel_size[0] = 1.0 / render_target_size.x; + state_buffer.screen_pixel_size[1] = 1.0 / render_target_size.y; + + state_buffer.time = state.time; + state_buffer.use_pixel_snap = p_snap_2d_vertices_to_pixel; + + state_buffer.directional_light_count = directional_light_count; + + RD::get_singleton()->buffer_update(state.canvas_state_buffer, 0, sizeof(State::Buffer), &state_buffer, true); } { //default filter/repeat @@ -1439,10 +1504,7 @@ void RasterizerCanvasRD::light_set_use_shadow(RID p_rid, bool p_enable) { cl->shadow.enabled = p_enable; } -void RasterizerCanvasRD::light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) { - CanvasLight *cl = canvas_light_owner.getornull(p_rid); - ERR_FAIL_COND(!cl->shadow.enabled); - +void RasterizerCanvasRD::_update_shadow_atlas() { if (state.shadow_fb == RID()) { //ah, we lack the shadow texture.. RD::get_singleton()->free(state.shadow_texture); //erase placeholder @@ -1474,6 +1536,12 @@ void RasterizerCanvasRD::light_update_shadow(RID p_rid, int p_shadow_index, cons state.shadow_fb = RD::get_singleton()->framebuffer_create(fb_textures); } +} +void RasterizerCanvasRD::light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) { + CanvasLight *cl = canvas_light_owner.getornull(p_rid); + ERR_FAIL_COND(!cl->shadow.enabled); + + _update_shadow_atlas(); cl->shadow.z_far = p_far; cl->shadow.y_offset = float(p_shadow_index * 2 + 1) / float(state.max_lights_per_render * 2); @@ -1547,6 +1615,86 @@ void RasterizerCanvasRD::light_update_shadow(RID p_rid, int p_shadow_index, cons } } +void RasterizerCanvasRD::light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) { + CanvasLight *cl = canvas_light_owner.getornull(p_rid); + ERR_FAIL_COND(!cl->shadow.enabled); + + _update_shadow_atlas(); + + Vector2 light_dir = p_light_xform.elements[1].normalized(); + + Vector2 center = p_clip_rect.position + p_clip_rect.size * 0.5; + + float to_edge_distance = ABS(light_dir.dot(p_clip_rect.get_support(light_dir)) - light_dir.dot(center)); + + Vector2 from_pos = center - light_dir * (to_edge_distance + p_cull_distance); + float distance = to_edge_distance * 2.0 + p_cull_distance; + float half_size = p_clip_rect.size.length() * 0.5; //shadow length, must keep this no matter the angle + + cl->shadow.z_far = distance; + cl->shadow.y_offset = float(p_shadow_index * 2 + 1) / float(state.max_lights_per_render * 2); + + Transform2D to_light_xform; + + to_light_xform[2] = from_pos; + to_light_xform[1] = light_dir; + to_light_xform[0] = -light_dir.tangent(); + + to_light_xform.invert(); + + Vector<Color> cc; + cc.push_back(Color(1, 1, 1, 1)); + + Rect2i rect(0, p_shadow_index * 2, state.shadow_texture_size, 2); + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(state.shadow_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, cc, 1.0, 0, rect); + + CameraMatrix projection; + projection.set_orthogonal(-half_size, half_size, -0.5, 0.5, 0.0, distance); + projection = projection * CameraMatrix(Transform().looking_at(Vector3(0, 1, 0), Vector3(0, 0, -1)).affine_inverse()); + + ShadowRenderPushConstant push_constant; + for (int y = 0; y < 4; y++) { + for (int x = 0; x < 4; x++) { + push_constant.projection[y * 4 + x] = projection.matrix[y][x]; + } + } + + push_constant.direction[0] = 0.0; + push_constant.direction[1] = 1.0; + push_constant.z_far = distance; + push_constant.pad = 0; + + LightOccluderInstance *instance = p_occluders; + + while (instance) { + OccluderPolygon *co = occluder_polygon_owner.getornull(instance->occluder); + + if (!co || co->index_array.is_null() || !(p_light_mask & instance->light_mask)) { + instance = instance->next; + continue; + } + + _update_transform_2d_to_mat2x4(to_light_xform * instance->xform_cache, push_constant.modelview); + + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, shadow_render.render_pipelines[co->cull_mode]); + RD::get_singleton()->draw_list_bind_vertex_array(draw_list, co->vertex_array); + RD::get_singleton()->draw_list_bind_index_array(draw_list, co->index_array); + RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(ShadowRenderPushConstant)); + + RD::get_singleton()->draw_list_draw(draw_list, true); + + instance = instance->next; + } + + RD::get_singleton()->draw_list_end(); + + Transform2D to_shadow; + to_shadow.elements[0].x = 1.0 / -(half_size * 2.0); + to_shadow.elements[2].x = 0.5; + + cl->shadow.directional_xform = to_shadow * to_light_xform; +} + RID RasterizerCanvasRD::occluder_polygon_create() { OccluderPolygon occluder; occluder.point_count = 0; diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h index 3412435367..b516f63cbf 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h @@ -75,7 +75,6 @@ class RasterizerCanvasRD : public RasterizerCanvas { FLAGS_CLIP_RECT_UV = (1 << 9), FLAGS_TRANSPOSE_RECT = (1 << 10), - FLAGS_USING_LIGHT_MASK = (1 << 11), FLAGS_NINEPACH_DRAW_CENTER = (1 << 12), FLAGS_USING_PARTICLES = (1 << 13), @@ -269,6 +268,7 @@ class RasterizerCanvasRD : public RasterizerCanvas { bool enabled = false; float z_far; float y_offset; + Transform2D directional_xform; } shadow; }; @@ -331,12 +331,13 @@ class RasterizerCanvasRD : public RasterizerCanvas { float screen_transform[16]; float canvas_normal_transform[16]; float canvas_modulate[4]; + float screen_pixel_size[2]; float time; uint32_t use_pixel_snap; - //uint32_t light_count; - //uint32_t pad[3]; + uint32_t directional_light_count; + uint32_t pad[3]; }; LightUniform *light_uniforms; @@ -355,6 +356,7 @@ class RasterizerCanvasRD : public RasterizerCanvas { uint32_t max_lights_per_item; double time; + } state; struct PushConstant { @@ -388,6 +390,7 @@ class RasterizerCanvasRD : public RasterizerCanvas { Item *items[MAX_RENDER_ITEMS]; + bool using_directional_lights = false; RID default_canvas_texture; RID default_canvas_group_shader; @@ -408,6 +411,8 @@ class RasterizerCanvasRD : public RasterizerCanvas { _FORCE_INLINE_ void _update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4); _FORCE_INLINE_ void _update_transform_to_mat4(const Transform &p_transform, float *p_mat4); + void _update_shadow_atlas(); + public: PolygonID request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>()); void free_polygon(PolygonID p_polygon); @@ -416,12 +421,13 @@ public: void light_set_texture(RID p_rid, RID p_texture); void light_set_use_shadow(RID p_rid, bool p_enable); void light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders); + void light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders); RID occluder_polygon_create(); void occluder_polygon_set_shape_as_lines(RID p_occluder, const Vector<Vector2> &p_lines); void occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode); - void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel); + void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_light_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel); void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) {} diff --git a/servers/rendering/rasterizer_rd/shaders/canvas.glsl b/servers/rendering/rasterizer_rd/shaders/canvas.glsl index b382c0d85f..2a0f94e733 100644 --- a/servers/rendering/rasterizer_rd/shaders/canvas.glsl +++ b/servers/rendering/rasterizer_rd/shaders/canvas.glsl @@ -249,7 +249,7 @@ vec4 light_compute( inout vec4 shadow_modulate, vec2 screen_uv, vec2 uv, - vec4 color) { + vec4 color, bool is_directional) { vec4 light = vec4(0.0); /* clang-format off */ LIGHT_SHADER_CODE @@ -302,6 +302,99 @@ float map_ninepatch_axis(float pixel, float draw_size, float tex_pixel_size, flo #endif +#ifdef USE_LIGHTING + +vec3 light_normal_compute(vec3 light_vec, vec3 normal, vec3 base_color, vec3 light_color, vec4 specular_shininess, bool specular_shininess_used) { + float cNdotL = max(0.0, dot(normal, light_vec)); + + if (specular_shininess_used) { + //blinn + vec3 view = vec3(0.0, 0.0, 1.0); // not great but good enough + vec3 half_vec = normalize(view + light_vec); + + float cNdotV = max(dot(normal, view), 0.0); + float cNdotH = max(dot(normal, half_vec), 0.0); + float cVdotH = max(dot(view, half_vec), 0.0); + float cLdotH = max(dot(light_vec, half_vec), 0.0); + float shininess = exp2(15.0 * specular_shininess.a + 1.0) * 0.25; + float blinn = pow(cNdotH, shininess); + blinn *= (shininess + 8.0) * (1.0 / (8.0 * M_PI)); + float s = (blinn) / max(4.0 * cNdotV * cNdotL, 0.75); + + return specular_shininess.rgb * light_color * s + light_color * base_color * cNdotL; + } else { + return light_color * base_color * cNdotL; + } +} + +//float distance = length(shadow_pos); +vec4 light_shadow_compute(uint light_base, vec4 light_color, vec4 shadow_uv +#ifdef LIGHT_SHADER_CODE_USED + , + vec3 shadow_modulate +#endif +) { + float shadow; + uint shadow_mode = light_array.data[light_base].flags & LIGHT_FLAGS_FILTER_MASK; + + if (shadow_mode == LIGHT_FLAGS_SHADOW_NEAREST) { + shadow = textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv, 0.0).x; + } else if (shadow_mode == LIGHT_FLAGS_SHADOW_PCF5) { + vec4 shadow_pixel_size = vec4(light_array.data[light_base].shadow_pixel_size, 0.0, 0.0, 0.0); + shadow = 0.0; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 2.0, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 2.0, 0.0).x; + shadow /= 5.0; + } else { //PCF13 + vec4 shadow_pixel_size = vec4(light_array.data[light_base].shadow_pixel_size, 0.0, 0.0, 0.0); + shadow = 0.0; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 6.0, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 5.0, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 4.0, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 3.0, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 2.0, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 2.0, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 3.0, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 4.0, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 5.0, 0.0).x; + shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 6.0, 0.0).x; + shadow /= 13.0; + } + + vec4 shadow_color = unpackUnorm4x8(light_array.data[light_base].shadow_color); +#ifdef LIGHT_SHADER_CODE_USED + shadow_color *= shadow_modulate; +#endif + + shadow_color.a *= light_color.a; //respect light alpha + + return mix(light_color, shadow_color, shadow); +} + +void light_blend_compute(uint light_base, vec4 light_color, inout vec3 color) { + uint blend_mode = light_array.data[light_base].flags & LIGHT_FLAGS_BLEND_MASK; + + switch (blend_mode) { + case LIGHT_FLAGS_BLEND_MODE_ADD: { + color.rgb += light_color.rgb * light_color.a; + } break; + case LIGHT_FLAGS_BLEND_MODE_SUB: { + color.rgb -= light_color.rgb * light_color.a; + } break; + case LIGHT_FLAGS_BLEND_MODE_MIX: { + color.rgb = mix(color.rgb, light_color.rgb, light_color.a); + } break; + } +} + +#endif + void main() { vec4 color = color_interp; vec2 uv = uv_interp; @@ -332,6 +425,7 @@ void main() { color *= texture(sampler2D(color_texture, texture_sampler), uv); uint light_count = (draw_data.flags >> FLAGS_LIGHT_COUNT_SHIFT) & 0xF; //max 16 lights + bool using_light = light_count > 0 || canvas_data.directional_light_count > 0; vec3 normal; @@ -341,7 +435,7 @@ void main() { bool normal_used = false; #endif - if (normal_used || (light_count > 0 && bool(draw_data.flags & FLAGS_DEFAULT_NORMAL_MAP_USED))) { + if (normal_used || (using_light && bool(draw_data.flags & FLAGS_DEFAULT_NORMAL_MAP_USED))) { normal.xy = texture(sampler2D(normal_texture, texture_sampler), uv).xy * vec2(2.0, -2.0) - vec2(1.0, -1.0); normal.z = sqrt(1.0 - dot(normal.xy, normal.xy)); normal_used = true; @@ -358,7 +452,7 @@ void main() { bool specular_shininess_used = false; #endif - if (specular_shininess_used || (light_count > 0 && normal_used && bool(draw_data.flags & FLAGS_DEFAULT_SPECULAR_MAP_USED))) { + if (specular_shininess_used || (using_light && normal_used && bool(draw_data.flags & FLAGS_DEFAULT_SPECULAR_MAP_USED))) { specular_shininess = texture(sampler2D(specular_texture, texture_sampler), uv); specular_shininess *= unpackUnorm4x8(draw_data.specular_shininess); specular_shininess_used = true; @@ -401,13 +495,52 @@ FRAGMENT_SHADER_CODE normal = normalize((canvas_data.canvas_normal_transform * vec4(normal, 0.0)).xyz); } - vec4 base_color = color; + vec3 base_color = color.rgb; if (bool(draw_data.flags & FLAGS_USING_LIGHT_MASK)) { color = vec4(0.0); //invisible by default due to using light mask } color *= canvas_data.canvas_modulation; #ifdef USE_LIGHTING + + // Directional Lights + + for (uint i = 0; i < canvas_data.directional_light_count; i++) { + uint light_base = i; + + vec2 direction = light_array.data[light_base].position; + vec4 light_color = light_array.data[light_base].color; + +#ifdef LIGHT_SHADER_CODE_USED + + vec4 shadow_modulate = vec4(1.0); + light_color = light_compute(light_vertex, direction, normal, light_color, light_color.a, specular_shininess, shadow_modulate, screen_uv, color, uv, true); +#else + + if (normal_used) { + vec3 light_vec = normalize(mix(vec3(direction, 0.0), vec3(0, 0, 1), light_array.data[light_base].height)); + light_color.rgb = light_normal_compute(light_vec, normal, base_color, light_color.rgb, specular_shininess, specular_shininess_used); + } +#endif + + if (bool(light_array.data[light_base].flags & LIGHT_FLAGS_HAS_SHADOW)) { + vec2 shadow_pos = (vec4(shadow_vertex, 0.0, 1.0) * mat4(light_array.data[light_base].shadow_matrix[0], light_array.data[light_base].shadow_matrix[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations. + + vec4 shadow_uv = vec4(shadow_pos.x, light_array.data[light_base].shadow_y_ofs, shadow_pos.y * light_array.data[light_base].shadow_zfar_inv, 1.0); + + light_color = light_shadow_compute(light_base, light_color, shadow_uv +#ifdef LIGHT_SHADER_CODE_USED + , + shadow_modulate +#endif + ); + } + + light_blend_compute(light_base, light_color, color.rgb); + } + + // Positional Lights + for (uint i = 0; i < MAX_LIGHTS_PER_ITEM; i++) { if (i >= light_count) { break; @@ -440,7 +573,7 @@ FRAGMENT_SHADER_CODE vec3 light_position = vec3(light_array.data[light_base].position, light_array.data[light_base].height); light_color.rgb *= light_base_color.rgb; - light_color = light_compute(light_vertex, light_position, normal, light_color, light_base_color.a, specular_shininess, shadow_modulate, screen_uv, color, uv); + light_color = light_compute(light_vertex, light_position, normal, light_color, light_base_color.a, specular_shininess, shadow_modulate, screen_uv, color, uv, false); #else light_color.rgb *= light_base_color.rgb * light_base_color.a; @@ -451,24 +584,7 @@ FRAGMENT_SHADER_CODE vec3 light_vec = normalize(light_pos - pos); float cNdotL = max(0.0, dot(normal, light_vec)); - if (specular_shininess_used) { - //blinn - vec3 view = vec3(0.0, 0.0, 1.0); // not great but good enough - vec3 half_vec = normalize(view + light_vec); - - float cNdotV = max(dot(normal, view), 0.0); - float cNdotH = max(dot(normal, half_vec), 0.0); - float cVdotH = max(dot(view, half_vec), 0.0); - float cLdotH = max(dot(light_vec, half_vec), 0.0); - float shininess = exp2(15.0 * specular_shininess.a + 1.0) * 0.25; - float blinn = pow(cNdotH, shininess); - blinn *= (shininess + 8.0) * (1.0 / (8.0 * M_PI)); - float s = (blinn) / max(4.0 * cNdotV * cNdotL, 0.75); - - light_color.rgb = specular_shininess.rgb * light_base_color.rgb * s + light_color.rgb * cNdotL; - } else { - light_color.rgb *= cNdotL; - } + light_color.rgb = light_normal_compute(light_vec, normal, base_color, light_color.rgb, specular_shininess, specular_shininess_used); } #endif if (any(lessThan(tex_uv, vec2(0.0, 0.0))) || any(greaterThanEqual(tex_uv, vec2(1.0, 1.0)))) { @@ -506,69 +622,17 @@ FRAGMENT_SHADER_CODE distance *= light_array.data[light_base].shadow_zfar_inv; //float distance = length(shadow_pos); - float shadow; - uint shadow_mode = light_array.data[light_base].flags & LIGHT_FLAGS_FILTER_MASK; - vec4 shadow_uv = vec4(tex_ofs, light_array.data[light_base].shadow_y_ofs, distance, 1.0); - if (shadow_mode == LIGHT_FLAGS_SHADOW_NEAREST) { - shadow = textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv, 0.0).x; - } else if (shadow_mode == LIGHT_FLAGS_SHADOW_PCF5) { - vec4 shadow_pixel_size = vec4(light_array.data[light_base].shadow_pixel_size, 0.0, 0.0, 0.0); - shadow = 0.0; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 2.0, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 2.0, 0.0).x; - shadow /= 5.0; - } else { //PCF13 - vec4 shadow_pixel_size = vec4(light_array.data[light_base].shadow_pixel_size, 0.0, 0.0, 0.0); - shadow = 0.0; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 6.0, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 5.0, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 4.0, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 3.0, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 2.0, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 2.0, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 3.0, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 4.0, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 5.0, 0.0).x; - shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 6.0, 0.0).x; - shadow /= 13.0; - } - - vec4 shadow_color = unpackUnorm4x8(light_array.data[light_base].shadow_color); + light_color = light_shadow_compute(light_base, light_color, shadow_uv #ifdef LIGHT_SHADER_CODE_USED - shadow_color *= shadow_modulate; + , + shadow_modulate #endif - - shadow_color.a *= light_color.a; //respect light alpha - - light_color = mix(light_color, shadow_color, shadow); - //light_color = mix(light_color, shadow_color, shadow); + ); } - uint blend_mode = light_array.data[light_base].flags & LIGHT_FLAGS_BLEND_MASK; - - switch (blend_mode) { - case LIGHT_FLAGS_BLEND_MODE_ADD: { - color.rgb += light_color.rgb * light_color.a; - } break; - case LIGHT_FLAGS_BLEND_MODE_SUB: { - color.rgb -= light_color.rgb * light_color.a; - } break; - case LIGHT_FLAGS_BLEND_MODE_MIX: { - color.rgb = mix(color.rgb, light_color.rgb, light_color.a); - } break; - case LIGHT_FLAGS_BLEND_MODE_MASK: { - light_color.a *= base_color.a; - color.rgb = mix(color.rgb, light_color.rgb, light_color.a); - } break; - } + light_blend_compute(light_base, light_color, color.rgb); } #endif diff --git a/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl b/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl index 1a226a87d3..bb39584cbb 100644 --- a/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl +++ b/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl @@ -68,7 +68,10 @@ layout(set = 0, binding = 1, std140) uniform CanvasData { float time; bool use_pixel_snap; - //uint light_count; + uint directional_light_count; + uint pad0; + uint pad1; + uint pad2; } canvas_data; diff --git a/servers/rendering/rendering_server_canvas.cpp b/servers/rendering/rendering_server_canvas.cpp index fd7c022d62..4480b79f75 100644 --- a/servers/rendering/rendering_server_canvas.cpp +++ b/servers/rendering/rendering_server_canvas.cpp @@ -37,7 +37,7 @@ static const int z_range = RS::CANVAS_ITEM_Z_MAX - RS::CANVAS_ITEM_Z_MIN + 1; -void RenderingServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel) { +void RenderingServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_directional_lights, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel) { RENDER_TIMESTAMP("Cull CanvasItem Tree"); memset(z_list, 0, z_range * sizeof(RasterizerCanvas::Item *)); @@ -68,7 +68,7 @@ void RenderingServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Can RENDER_TIMESTAMP("Render Canvas Items"); - RSG::canvas_render->canvas_render_items(p_to_render_target, list, p_modulate, p_lights, p_transform, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); + RSG::canvas_render->canvas_render_items(p_to_render_target, list, p_modulate, p_lights, p_directional_lights, p_transform, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); } void _collect_ysort_children(RenderingServerCanvas::Item *p_canvas_item, Transform2D p_transform, RenderingServerCanvas::Item *p_material_owner, RenderingServerCanvas::Item **r_items, int &r_index) { @@ -298,28 +298,7 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo } } -void RenderingServerCanvas::_light_mask_canvas_items(int p_z, RasterizerCanvas::Item *p_canvas_item, RasterizerCanvas::Light *p_masked_lights) { - if (!p_masked_lights) { - return; - } - - RasterizerCanvas::Item *ci = p_canvas_item; - - while (ci) { - RasterizerCanvas::Light *light = p_masked_lights; - while (light) { - if (ci->light_mask & light->item_mask && p_z >= light->z_min && p_z <= light->z_max && ci->global_rect_cache.intersects_transformed(light->xform_cache, light->rect_cache)) { - ci->light_masked = true; - } - - light = light->mask_next_ptr; - } - - ci = ci->next; - } -} - -void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_masked_lights, const Rect2 &p_clip_rect, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel) { +void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_directional_lights, const Rect2 &p_clip_rect, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel) { RENDER_TIMESTAMP(">Render Canvas"); snapping_2d_transforms_to_pixel = p_snap_2d_transforms_to_pixel; @@ -341,26 +320,26 @@ void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas, } if (!has_mirror) { - _render_canvas_item_tree(p_render_target, ci, l, nullptr, p_transform, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); + _render_canvas_item_tree(p_render_target, ci, l, nullptr, p_transform, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); } else { //used for parallaxlayer mirroring for (int i = 0; i < l; i++) { const Canvas::ChildItem &ci2 = p_canvas->child_items[i]; - _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, p_transform, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); + _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, p_transform, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); //mirroring (useful for scrolling backgrounds) if (ci2.mirror.x != 0) { Transform2D xform2 = p_transform * Transform2D(0, Vector2(ci2.mirror.x, 0)); - _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); + _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); } if (ci2.mirror.y != 0) { Transform2D xform2 = p_transform * Transform2D(0, Vector2(0, ci2.mirror.y)); - _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); + _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); } if (ci2.mirror.y != 0 && ci2.mirror.x != 0) { Transform2D xform2 = p_transform * Transform2D(0, ci2.mirror); - _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); + _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); } } } @@ -1040,13 +1019,38 @@ RID RenderingServerCanvas::canvas_light_create() { return canvas_light_owner.make_rid(clight); } +void RenderingServerCanvas::canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode) { + RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); + ERR_FAIL_COND(!clight); + + if (clight->mode == p_mode) { + return; + } + + RID canvas = clight->canvas; + + if (canvas.is_valid()) { + canvas_light_attach_to_canvas(p_light, RID()); + } + + clight->mode = p_mode; + + if (canvas.is_valid()) { + canvas_light_attach_to_canvas(p_light, canvas); + } +} + void RenderingServerCanvas::canvas_light_attach_to_canvas(RID p_light, RID p_canvas) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); if (clight->canvas.is_valid()) { Canvas *canvas = canvas_owner.getornull(clight->canvas); - canvas->lights.erase(clight); + if (clight->mode == RS::CANVAS_LIGHT_MODE_POINT) { + canvas->lights.erase(clight); + } else { + canvas->directional_lights.erase(clight); + } } if (!canvas_owner.owns(p_canvas)) { @@ -1057,7 +1061,11 @@ void RenderingServerCanvas::canvas_light_attach_to_canvas(RID p_light, RID p_can if (clight->canvas.is_valid()) { Canvas *canvas = canvas_owner.getornull(clight->canvas); - canvas->lights.insert(clight); + if (clight->mode == RS::CANVAS_LIGHT_MODE_POINT) { + canvas->lights.insert(clight); + } else { + canvas->directional_lights.insert(clight); + } } } @@ -1068,7 +1076,7 @@ void RenderingServerCanvas::canvas_light_set_enabled(RID p_light, bool p_enabled clight->enabled = p_enabled; } -void RenderingServerCanvas::canvas_light_set_scale(RID p_light, float p_scale) { +void RenderingServerCanvas::canvas_light_set_texture_scale(RID p_light, float p_scale) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); @@ -1152,11 +1160,18 @@ void RenderingServerCanvas::canvas_light_set_item_shadow_cull_mask(RID p_light, clight->item_shadow_mask = p_mask; } -void RenderingServerCanvas::canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode) { +void RenderingServerCanvas::canvas_light_set_directional_distance(RID p_light, float p_distance) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); - clight->mode = p_mode; + clight->directional_distance = p_distance; +} + +void RenderingServerCanvas::canvas_light_set_blend_mode(RID p_light, RS::CanvasLightBlendMode p_mode) { + RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); + ERR_FAIL_COND(!clight); + + clight->blend_mode = p_mode; } void RenderingServerCanvas::canvas_light_set_shadow_enabled(RID p_light, bool p_enabled) { diff --git a/servers/rendering/rendering_server_canvas.h b/servers/rendering/rendering_server_canvas.h index a9a81888aa..36e2f77e95 100644 --- a/servers/rendering/rendering_server_canvas.h +++ b/servers/rendering/rendering_server_canvas.h @@ -116,6 +116,7 @@ public: }; Set<RasterizerCanvas::Light *> lights; + Set<RasterizerCanvas::Light *> directional_lights; Set<RasterizerCanvas::LightOccluderInstance *> occluders; @@ -155,15 +156,14 @@ public: bool snapping_2d_transforms_to_pixel = false; private: - void _render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel); + void _render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_directional_lights, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel); void _cull_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); - void _light_mask_canvas_items(int p_z, RasterizerCanvas::Item *p_canvas_item, RasterizerCanvas::Light *p_masked_lights); RasterizerCanvas::Item **z_list; RasterizerCanvas::Item **z_last_list; public: - void render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_masked_lights, const Rect2 &p_clip_rect, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel); + void render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_directional_lights, const Rect2 &p_clip_rect, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel); RID canvas_create(); void canvas_set_item_mirroring(RID p_canvas, RID p_item, const Point2 &p_mirroring); @@ -220,9 +220,10 @@ public: void canvas_item_set_canvas_group_mode(RID p_item, RS::CanvasGroupMode p_mode, float p_clear_margin = 5.0, bool p_fit_empty = false, float p_fit_margin = 0.0, bool p_blur_mipmaps = false); RID canvas_light_create(); + void canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode); void canvas_light_attach_to_canvas(RID p_light, RID p_canvas); void canvas_light_set_enabled(RID p_light, bool p_enabled); - void canvas_light_set_scale(RID p_light, float p_scale); + void canvas_light_set_texture_scale(RID p_light, float p_scale); void canvas_light_set_transform(RID p_light, const Transform2D &p_transform); void canvas_light_set_texture(RID p_light, RID p_texture); void canvas_light_set_texture_offset(RID p_light, const Vector2 &p_offset); @@ -233,8 +234,9 @@ public: void canvas_light_set_layer_range(RID p_light, int p_min_layer, int p_max_layer); void canvas_light_set_item_cull_mask(RID p_light, int p_mask); void canvas_light_set_item_shadow_cull_mask(RID p_light, int p_mask); + void canvas_light_set_directional_distance(RID p_light, float p_distance); - void canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode); + void canvas_light_set_blend_mode(RID p_light, RS::CanvasLightBlendMode p_mode); void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled); void canvas_light_set_shadow_filter(RID p_light, RS::CanvasLightShadowFilter p_filter); diff --git a/servers/rendering/rendering_server_raster.h b/servers/rendering/rendering_server_raster.h index a89d4db1f8..daad706f8e 100644 --- a/servers/rendering/rendering_server_raster.h +++ b/servers/rendering/rendering_server_raster.h @@ -748,9 +748,12 @@ public: BIND6(canvas_item_set_canvas_group_mode, RID, CanvasGroupMode, float, bool, float, bool) BIND0R(RID, canvas_light_create) + + BIND2(canvas_light_set_mode, RID, CanvasLightMode) + BIND2(canvas_light_attach_to_canvas, RID, RID) BIND2(canvas_light_set_enabled, RID, bool) - BIND2(canvas_light_set_scale, RID, float) + BIND2(canvas_light_set_texture_scale, RID, float) BIND2(canvas_light_set_transform, RID, const Transform2D &) BIND2(canvas_light_set_texture, RID, RID) BIND2(canvas_light_set_texture_offset, RID, const Vector2 &) @@ -761,8 +764,9 @@ public: BIND3(canvas_light_set_layer_range, RID, int, int) BIND2(canvas_light_set_item_cull_mask, RID, int) BIND2(canvas_light_set_item_shadow_cull_mask, RID, int) + BIND2(canvas_light_set_directional_distance, RID, float) - BIND2(canvas_light_set_mode, RID, CanvasLightMode) + BIND2(canvas_light_set_blend_mode, RID, CanvasLightBlendMode) BIND2(canvas_light_set_shadow_enabled, RID, bool) BIND2(canvas_light_set_shadow_filter, RID, CanvasLightShadowFilter) diff --git a/servers/rendering/rendering_server_viewport.cpp b/servers/rendering/rendering_server_viewport.cpp index b5d8f0da40..23911faa5d 100644 --- a/servers/rendering/rendering_server_viewport.cpp +++ b/servers/rendering/rendering_server_viewport.cpp @@ -142,11 +142,15 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: Rect2 clip_rect(0, 0, p_viewport->size.x, p_viewport->size.y); RasterizerCanvas::Light *lights = nullptr; RasterizerCanvas::Light *lights_with_shadow = nullptr; - RasterizerCanvas::Light *lights_with_mask = nullptr; + + RasterizerCanvas::Light *directional_lights = nullptr; + RasterizerCanvas::Light *directional_lights_with_shadow = nullptr; + Rect2 shadow_rect; int light_count = 0; int shadow_count = 0; + int directional_light_count = 0; RENDER_TIMESTAMP("Cull Canvas Lights"); for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { @@ -186,10 +190,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: lights_with_shadow = cl; cl->radius_cache = cl->rect_cache.size.length(); } - if (cl->mode == RS::CANVAS_LIGHT_MODE_MASK) { - cl->mask_next_ptr = lights_with_mask; - lights_with_mask = cl; - } light_count++; } @@ -199,6 +199,26 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: } } + for (Set<RasterizerCanvas::Light *>::Element *F = canvas->directional_lights.front(); F; F = F->next()) { + RasterizerCanvas::Light *cl = F->get(); + if (cl->enabled) { + cl->filter_next_ptr = directional_lights; + directional_lights = cl; + cl->xform_cache = xf * cl->xform; + cl->xform_cache.elements[2] = Vector2(); //translation is pointless + if (cl->use_shadow) { + cl->shadows_next_ptr = directional_lights_with_shadow; + directional_lights_with_shadow = cl; + } + + directional_light_count++; + + if (directional_light_count == RS::MAX_2D_DIRECTIONAL_LIGHTS) { + break; + } + } + } + canvas_map[Viewport::CanvasKey(E->key(), E->get().layer, E->get().sublayer)] = &E->get(); } @@ -240,6 +260,90 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: RENDER_TIMESTAMP("<End rendering 2D Shadows"); } + if (directional_lights_with_shadow) { + //update shadows if any + RasterizerCanvas::Light *light = directional_lights_with_shadow; + while (light) { + Vector2 light_dir = -light->xform_cache.elements[1].normalized(); // Y is light direction + float cull_distance = light->directional_distance; + + Vector2 light_dir_sign; + light_dir_sign.x = (ABS(light_dir.x) < CMP_EPSILON) ? 0.0 : ((light_dir.x > 0.0) ? 1.0 : -1.0); + light_dir_sign.y = (ABS(light_dir.y) < CMP_EPSILON) ? 0.0 : ((light_dir.y > 0.0) ? 1.0 : -1.0); + + Vector2 points[6]; + int point_count = 0; + + for (int j = 0; j < 4; j++) { + static const Vector2 signs[4] = { Vector2(1, 1), Vector2(1, 0), Vector2(0, 0), Vector2(0, 1) }; + Vector2 sign_cmp = signs[j] * 2.0 - Vector2(1.0, 1.0); + Vector2 point = clip_rect.position + clip_rect.size * signs[j]; + + if (sign_cmp == light_dir_sign) { + //both point in same direction, plot offseted + points[point_count++] = point + light_dir * cull_distance; + } else if (sign_cmp.x == light_dir_sign.x || sign_cmp.y == light_dir_sign.y) { + int next_j = (j + 1) % 4; + Vector2 next_sign_cmp = signs[next_j] * 2.0 - Vector2(1.0, 1.0); + + //one point in the same direction, plot segment + + if (next_sign_cmp.x == light_dir_sign.x || next_sign_cmp.y == light_dir_sign.y) { + if (light_dir_sign.x != 0.0 || light_dir_sign.y != 0.0) { + points[point_count++] = point; + } + points[point_count++] = point + light_dir * cull_distance; + } else { + points[point_count++] = point + light_dir * cull_distance; + if (light_dir_sign.x != 0.0 || light_dir_sign.y != 0.0) { + points[point_count++] = point; + } + } + } else { + //plot normally + points[point_count++] = point; + } + } + + Vector2 xf_points[6]; + + RasterizerCanvas::LightOccluderInstance *occluders = nullptr; + + RENDER_TIMESTAMP(">Render Directional 2D Shadows"); + + //make list of occluders + int occ_cullded = 0; + for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { + RenderingServerCanvas::Canvas *canvas = static_cast<RenderingServerCanvas::Canvas *>(E->get().canvas); + Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size); + + for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) { + if (!F->get()->enabled) { + continue; + } + F->get()->xform_cache = xf * F->get()->xform; + Transform2D localizer = F->get()->xform_cache.affine_inverse(); + + for (int j = 0; j < point_count; j++) { + xf_points[j] = localizer.xform(points[j]); + } + if (F->get()->aabb_cache.intersects_filled_polygon(xf_points, point_count)) { + F->get()->next = occluders; + occluders = F->get(); + occ_cullded++; + } + } + } + + RSG::canvas_render->light_update_directional_shadow(light->light_internal, shadow_count++, light->xform_cache, light->item_shadow_mask, cull_distance, clip_rect, occluders); + + light = light->shadows_next_ptr; + } + + //RSG::canvas_render->reset_canvas(); + RENDER_TIMESTAMP("<Render Directional 2D Shadows"); + } + if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().get_layer() > scenario_canvas_max_layer) { if (!can_draw_3d) { RSG::scene->render_empty_scene(p_viewport->render_buffers, p_viewport->scenario, p_viewport->shadow_atlas); @@ -255,6 +359,7 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: Transform2D xform = _canvas_get_transform(p_viewport, canvas, E->get(), clip_rect.size); RasterizerCanvas::Light *canvas_lights = nullptr; + RasterizerCanvas::Light *canvas_directional_lights = nullptr; RasterizerCanvas::Light *ptr = lights; while (ptr) { @@ -265,7 +370,16 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: ptr = ptr->filter_next_ptr; } - RSG::canvas->render_canvas(p_viewport->render_target, canvas, xform, canvas_lights, lights_with_mask, clip_rect, p_viewport->texture_filter, p_viewport->texture_repeat, p_viewport->snap_2d_transforms_to_pixel, p_viewport->snap_2d_vertices_to_pixel); + ptr = directional_lights; + while (ptr) { + if (E->get()->layer >= ptr->layer_min && E->get()->layer <= ptr->layer_max) { + ptr->next_ptr = canvas_directional_lights; + canvas_directional_lights = ptr; + } + ptr = ptr->filter_next_ptr; + } + + RSG::canvas->render_canvas(p_viewport->render_target, canvas, xform, canvas_lights, canvas_directional_lights, clip_rect, p_viewport->texture_filter, p_viewport->texture_repeat, p_viewport->snap_2d_transforms_to_pixel, p_viewport->snap_2d_vertices_to_pixel); i++; if (scenario_draw_canvas_bg && E->key().get_layer() >= scenario_canvas_max_layer) { diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h index 42f1b5bcc8..237ba012fa 100644 --- a/servers/rendering/rendering_server_wrap_mt.h +++ b/servers/rendering/rendering_server_wrap_mt.h @@ -647,9 +647,12 @@ public: FUNC6(canvas_item_set_canvas_group_mode, RID, CanvasGroupMode, float, bool, float, bool) FUNC0R(RID, canvas_light_create) + + FUNC2(canvas_light_set_mode, RID, CanvasLightMode) + FUNC2(canvas_light_attach_to_canvas, RID, RID) FUNC2(canvas_light_set_enabled, RID, bool) - FUNC2(canvas_light_set_scale, RID, float) + FUNC2(canvas_light_set_texture_scale, RID, float) FUNC2(canvas_light_set_transform, RID, const Transform2D &) FUNC2(canvas_light_set_texture, RID, RID) FUNC2(canvas_light_set_texture_offset, RID, const Vector2 &) @@ -660,8 +663,9 @@ public: FUNC3(canvas_light_set_layer_range, RID, int, int) FUNC2(canvas_light_set_item_cull_mask, RID, int) FUNC2(canvas_light_set_item_shadow_cull_mask, RID, int) + FUNC2(canvas_light_set_directional_distance, RID, float) - FUNC2(canvas_light_set_mode, RID, CanvasLightMode) + FUNC2(canvas_light_set_blend_mode, RID, CanvasLightBlendMode) FUNC2(canvas_light_set_shadow_enabled, RID, bool) FUNC2(canvas_light_set_shadow_filter, RID, CanvasLightShadowFilter) diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 42a77101f7..121bf3ee92 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -1833,7 +1833,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("canvas_light_create"), &RenderingServer::canvas_light_create); ClassDB::bind_method(D_METHOD("canvas_light_attach_to_canvas", "light", "canvas"), &RenderingServer::canvas_light_attach_to_canvas); ClassDB::bind_method(D_METHOD("canvas_light_set_enabled", "light", "enabled"), &RenderingServer::canvas_light_set_enabled); - ClassDB::bind_method(D_METHOD("canvas_light_set_scale", "light", "scale"), &RenderingServer::canvas_light_set_scale); + ClassDB::bind_method(D_METHOD("canvas_light_set_texture_scale", "light", "scale"), &RenderingServer::canvas_light_set_texture_scale); ClassDB::bind_method(D_METHOD("canvas_light_set_transform", "light", "transform"), &RenderingServer::canvas_light_set_transform); ClassDB::bind_method(D_METHOD("canvas_light_set_texture", "light", "texture"), &RenderingServer::canvas_light_set_texture); ClassDB::bind_method(D_METHOD("canvas_light_set_texture_offset", "light", "offset"), &RenderingServer::canvas_light_set_texture_offset); @@ -2190,10 +2190,16 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(CANVAS_ITEM_TEXTURE_REPEAT_MIRROR); BIND_ENUM_CONSTANT(CANVAS_ITEM_TEXTURE_REPEAT_MAX); - BIND_ENUM_CONSTANT(CANVAS_LIGHT_MODE_ADD); - BIND_ENUM_CONSTANT(CANVAS_LIGHT_MODE_SUB); - BIND_ENUM_CONSTANT(CANVAS_LIGHT_MODE_MIX); - BIND_ENUM_CONSTANT(CANVAS_LIGHT_MODE_MASK); + BIND_ENUM_CONSTANT(CANVAS_GROUP_MODE_DISABLED); + BIND_ENUM_CONSTANT(CANVAS_GROUP_MODE_OPAQUE); + BIND_ENUM_CONSTANT(CANVAS_GROUP_MODE_TRANSPARENT); + + BIND_ENUM_CONSTANT(CANVAS_LIGHT_MODE_POINT); + BIND_ENUM_CONSTANT(CANVAS_LIGHT_MODE_DIRECTIONAL); + + BIND_ENUM_CONSTANT(CANVAS_LIGHT_BLEND_MODE_ADD); + BIND_ENUM_CONSTANT(CANVAS_LIGHT_BLEND_MODE_SUB); + BIND_ENUM_CONSTANT(CANVAS_LIGHT_BLEND_MODE_MIX); BIND_ENUM_CONSTANT(CANVAS_LIGHT_FILTER_NONE); BIND_ENUM_CONSTANT(CANVAS_LIGHT_FILTER_PCF5); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index a33215a882..3aa15623eb 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -77,6 +77,7 @@ public: CANVAS_ITEM_Z_MAX = 4096, MAX_GLOW_LEVELS = 7, MAX_CURSORS = 8, + MAX_2D_DIRECTIONAL_LIGHTS = 8 }; /* TEXTURE API */ @@ -1195,12 +1196,17 @@ public: virtual void canvas_item_set_canvas_group_mode(RID p_item, CanvasGroupMode p_mode, float p_clear_margin = 5.0, bool p_fit_empty = false, float p_fit_margin = 0.0, bool p_blur_mipmaps = false) = 0; virtual RID canvas_light_create() = 0; + + enum CanvasLightMode { + CANVAS_LIGHT_MODE_POINT, + CANVAS_LIGHT_MODE_DIRECTIONAL, + }; + + virtual void canvas_light_set_mode(RID p_light, CanvasLightMode p_mode) = 0; + virtual void canvas_light_attach_to_canvas(RID p_light, RID p_canvas) = 0; virtual void canvas_light_set_enabled(RID p_light, bool p_enabled) = 0; - virtual void canvas_light_set_scale(RID p_light, float p_scale) = 0; virtual void canvas_light_set_transform(RID p_light, const Transform2D &p_transform) = 0; - virtual void canvas_light_set_texture(RID p_light, RID p_texture) = 0; - virtual void canvas_light_set_texture_offset(RID p_light, const Vector2 &p_offset) = 0; virtual void canvas_light_set_color(RID p_light, const Color &p_color) = 0; virtual void canvas_light_set_height(RID p_light, float p_height) = 0; virtual void canvas_light_set_energy(RID p_light, float p_energy) = 0; @@ -1209,14 +1215,19 @@ public: virtual void canvas_light_set_item_cull_mask(RID p_light, int p_mask) = 0; virtual void canvas_light_set_item_shadow_cull_mask(RID p_light, int p_mask) = 0; - enum CanvasLightMode { - CANVAS_LIGHT_MODE_ADD, - CANVAS_LIGHT_MODE_SUB, - CANVAS_LIGHT_MODE_MIX, - CANVAS_LIGHT_MODE_MASK, + virtual void canvas_light_set_directional_distance(RID p_light, float p_distance) = 0; + + virtual void canvas_light_set_texture_scale(RID p_light, float p_scale) = 0; + virtual void canvas_light_set_texture(RID p_light, RID p_texture) = 0; + virtual void canvas_light_set_texture_offset(RID p_light, const Vector2 &p_offset) = 0; + + enum CanvasLightBlendMode { + CANVAS_LIGHT_BLEND_MODE_ADD, + CANVAS_LIGHT_BLEND_MODE_SUB, + CANVAS_LIGHT_BLEND_MODE_MIX, }; - virtual void canvas_light_set_mode(RID p_light, CanvasLightMode p_mode) = 0; + virtual void canvas_light_set_blend_mode(RID p_light, CanvasLightBlendMode p_mode) = 0; enum CanvasLightShadowFilter { CANVAS_LIGHT_FILTER_NONE, @@ -1434,7 +1445,9 @@ VARIANT_ENUM_CAST(RenderingServer::ShadowCastingSetting); VARIANT_ENUM_CAST(RenderingServer::NinePatchAxisMode); VARIANT_ENUM_CAST(RenderingServer::CanvasItemTextureFilter); VARIANT_ENUM_CAST(RenderingServer::CanvasItemTextureRepeat); +VARIANT_ENUM_CAST(RenderingServer::CanvasGroupMode); VARIANT_ENUM_CAST(RenderingServer::CanvasLightMode); +VARIANT_ENUM_CAST(RenderingServer::CanvasLightBlendMode); VARIANT_ENUM_CAST(RenderingServer::CanvasLightShadowFilter); VARIANT_ENUM_CAST(RenderingServer::CanvasOccluderPolygonCullMode); VARIANT_ENUM_CAST(RenderingServer::GlobalVariableType); |