summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--DONORS.md2
-rw-r--r--core/image.cpp19
-rw-r--r--core/io/ip.cpp4
-rw-r--r--core/io/resource_import.cpp2
-rw-r--r--core/io/stream_peer_tcp.cpp3
-rw-r--r--core/math/quat.cpp2
-rw-r--r--core/os/os.h2
-rw-r--r--doc/classes/Control.xml2
-rw-r--r--doc/classes/KinematicBody.xml2
-rw-r--r--doc/classes/Node.xml6
-rw-r--r--doc/classes/PhysicsMaterial.xml4
-rw-r--r--doc/classes/ProjectSettings.xml3
-rwxr-xr-x[-rw-r--r--]doc/classes/UndoRedo.xml37
-rw-r--r--doc/classes/Vector2.xml12
-rw-r--r--doc/classes/Vector3.xml14
-rw-r--r--doc/classes/VideoStream.xml1
-rw-r--r--doc/classes/ViewportContainer.xml3
-rw-r--r--doc/classes/WindowDialog.xml2
-rw-r--r--drivers/dummy/rasterizer_dummy.h4
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp33
-rw-r--r--drivers/gles2/rasterizer_gles2.h3
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.cpp19
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.h4
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp23
-rw-r--r--drivers/gles3/rasterizer_gles3.h3
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp23
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h8
-rw-r--r--drivers/unix/os_unix.cpp2
-rw-r--r--drivers/unix/os_unix.h2
-rw-r--r--editor/editor_export.cpp3
-rw-r--r--editor/editor_profiler.cpp5
-rw-r--r--editor/editor_run.cpp4
-rw-r--r--editor/import/editor_scene_importer_gltf.cpp18
-rw-r--r--editor/import/resource_importer_texture.cpp48
-rw-r--r--editor/plugins/item_list_editor_plugin.cpp2
-rw-r--r--editor/plugins/script_text_editor.cpp10
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp1
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp42
-rw-r--r--editor/plugins/tile_set_editor_plugin.cpp32
-rw-r--r--editor/scene_tree_dock.cpp6
-rw-r--r--main/main.cpp4
-rw-r--r--main/splash_editor.pngbin32577 -> 37619 bytes
-rw-r--r--methods.py2
-rw-r--r--modules/cvtt/image_compress_cvtt.cpp4
-rw-r--r--modules/gdscript/gdscript_compiler.cpp19
-rw-r--r--modules/gdscript/gdscript_function.cpp16
-rw-r--r--modules/gdscript/gdscript_function.h1
-rw-r--r--modules/gdscript/gdscript_parser.cpp46
-rw-r--r--modules/gdscript/gdscript_parser.h1
-rw-r--r--modules/mono/editor/bindings_generator.cpp48
-rw-r--r--modules/mono/editor/bindings_generator.h11
-rw-r--r--modules/mono/glue/cs_files/Basis.cs2
-rw-r--r--modules/mono/glue/cs_files/Quat.cs97
-rw-r--r--modules/squish/image_compress_squish.cpp4
-rw-r--r--modules/webm/libvpx/SCsub12
-rw-r--r--platform/android/detect.py3
-rw-r--r--platform/android/os_android.cpp64
-rw-r--r--platform/iphone/os_iphone.cpp5
-rw-r--r--platform/javascript/detect.py1
-rw-r--r--platform/javascript/os_javascript.cpp62
-rw-r--r--platform/osx/os_osx.mm52
-rw-r--r--platform/uwp/os_uwp.cpp88
-rw-r--r--platform/windows/context_gl_win.cpp7
-rw-r--r--platform/windows/os_windows.cpp111
-rw-r--r--platform/windows/os_windows.h2
-rw-r--r--platform/x11/context_gl_x11.cpp63
-rw-r--r--platform/x11/os_x11.cpp77
-rw-r--r--scene/2d/physics_body_2d.cpp4
-rw-r--r--scene/animation/animation_node_state_machine.cpp2
-rw-r--r--scene/resources/material.cpp2
-rw-r--r--scene/resources/mesh.cpp9
-rw-r--r--scene/resources/texture.cpp2
-rw-r--r--scene/resources/tile_set.cpp2
-rw-r--r--servers/audio_server.cpp6
-rw-r--r--thirdparty/cvtt/ConvectionKernels.cpp10
-rw-r--r--thirdparty/libvpx/vpx_config.h7
-rw-r--r--version.py2
77 files changed, 822 insertions, 441 deletions
diff --git a/DONORS.md b/DONORS.md
index ddfcd1057b..6153043318 100644
--- a/DONORS.md
+++ b/DONORS.md
@@ -13,11 +13,11 @@ generous deed immortalized in the next stable release of Godot Engine.
## Platinum sponsors
Enjin Coin <https://enjincoin.io>
+ GameDev.TV <https://gdev.tv/godot>
## Gold sponsors
Gamblify <https://www.gamblify.com>
- GameDev.TV <https://www.gamedev.tv>
## Mini sponsors
diff --git a/core/image.cpp b/core/image.cpp
index 7778169995..08bb9a35c3 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -1133,20 +1133,23 @@ template <class Component, int CC, bool renormalize,
static void _generate_po2_mipmap(const Component *p_src, Component *p_dst, uint32_t p_width, uint32_t p_height) {
//fast power of 2 mipmap generation
- uint32_t dst_w = p_width >> 1;
- uint32_t dst_h = p_height >> 1;
+ uint32_t dst_w = MAX(p_width >> 1, 1);
+ uint32_t dst_h = MAX(p_height >> 1, 1);
+
+ int right_step = (p_width == 1) ? 0 : CC;
+ int down_step = (p_height == 1) ? 0 : (p_width * CC);
for (uint32_t i = 0; i < dst_h; i++) {
- const Component *rup_ptr = &p_src[i * 2 * p_width * CC];
- const Component *rdown_ptr = rup_ptr + p_width * CC;
+ const Component *rup_ptr = &p_src[i * 2 * down_step];
+ const Component *rdown_ptr = rup_ptr + down_step;
Component *dst_ptr = &p_dst[i * dst_w * CC];
uint32_t count = dst_w;
while (count--) {
for (int j = 0; j < CC; j++) {
- average_func(dst_ptr[j], rup_ptr[j], rup_ptr[j + CC], rdown_ptr[j], rdown_ptr[j + CC]);
+ average_func(dst_ptr[j], rup_ptr[j], rup_ptr[j + right_step], rdown_ptr[j], rdown_ptr[j + right_step]);
}
if (renormalize) {
@@ -1154,8 +1157,8 @@ static void _generate_po2_mipmap(const Component *p_src, Component *p_dst, uint3
}
dst_ptr += CC;
- rup_ptr += CC * 2;
- rdown_ptr += CC * 2;
+ rup_ptr += right_step * 2;
+ rdown_ptr += right_step * 2;
}
}
}
@@ -1313,7 +1316,7 @@ Error Image::generate_mipmaps(bool p_renormalize) {
int prev_h = height;
int prev_w = width;
- for (int i = 1; i < mmcount; i++) {
+ for (int i = 1; i <= mmcount; i++) {
int ofs, w, h;
_get_mipmap_offset_and_size(i, ofs, w, h);
diff --git a/core/io/ip.cpp b/core/io/ip.cpp
index 66bd96df4f..82c94ca0b2 100644
--- a/core/io/ip.cpp
+++ b/core/io/ip.cpp
@@ -117,7 +117,7 @@ IP_Address IP::resolve_hostname(const String &p_hostname, IP::Type p_type) {
resolver->mutex->lock();
String key = _IP_ResolverPrivate::get_cache_key(p_hostname, p_type);
- if (resolver->cache.has(key)) {
+ if (resolver->cache.has(key) && resolver->cache[key].is_valid()) {
IP_Address res = resolver->cache[key];
resolver->mutex->unlock();
return res;
@@ -144,7 +144,7 @@ IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Typ
String key = _IP_ResolverPrivate::get_cache_key(p_hostname, p_type);
resolver->queue[id].hostname = p_hostname;
resolver->queue[id].type = p_type;
- if (resolver->cache.has(key)) {
+ if (resolver->cache.has(key) && resolver->cache[key].is_valid()) {
resolver->queue[id].response = resolver->cache[key];
resolver->queue[id].status = IP::RESOLVER_STATUS_DONE;
} else {
diff --git a/core/io/resource_import.cpp b/core/io/resource_import.cpp
index 83e8a40da9..cfe6655504 100644
--- a/core/io/resource_import.cpp
+++ b/core/io/resource_import.cpp
@@ -78,7 +78,7 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
if (assign != String()) {
if (!path_found && assign.begins_with("path.") && r_path_and_type.path == String()) {
String feature = assign.get_slicec('.', 1);
- if (feature == "fallback" || OS::get_singleton()->has_feature(feature)) {
+ if (OS::get_singleton()->has_feature(feature)) {
r_path_and_type.path = value;
path_found = true; //first match must have priority
}
diff --git a/core/io/stream_peer_tcp.cpp b/core/io/stream_peer_tcp.cpp
index 5d008904ff..54ebb3ae0d 100644
--- a/core/io/stream_peer_tcp.cpp
+++ b/core/io/stream_peer_tcp.cpp
@@ -43,8 +43,7 @@ Error StreamPeerTCP::_connect(const String &p_address, int p_port) {
return ERR_CANT_RESOLVE;
}
- connect_to_host(ip, p_port);
- return OK;
+ return connect_to_host(ip, p_port);
}
void StreamPeerTCP::_bind_methods() {
diff --git a/core/math/quat.cpp b/core/math/quat.cpp
index 67c9048a41..2251571146 100644
--- a/core/math/quat.cpp
+++ b/core/math/quat.cpp
@@ -134,7 +134,7 @@ Quat Quat::normalized() const {
}
bool Quat::is_normalized() const {
- return Math::is_equal_approx(length(), 1.0);
+ return Math::is_equal_approx(length_squared(), 1.0);
}
Quat Quat::inverse() const {
diff --git a/core/os/os.h b/core/os/os.h
index 6f9a72d451..100af95ef1 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -256,7 +256,7 @@ public:
virtual String get_executable_path() const;
virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false) = 0;
- virtual Error kill(const ProcessID &p_pid, const int p_max_wait_msec = -1) = 0;
+ virtual Error kill(const ProcessID &p_pid) = 0;
virtual int get_process_id() const;
virtual Error shell_open(String p_uri);
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index 4301102e4a..8575a1f498 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -38,7 +38,7 @@
<argument index="0" name="event" type="InputEvent">
</argument>
<description>
- The node's parent forwards input events to this method. Use it to process and accept inputs on UI elements. See [method accept_event].
+ Use this method to process and accept inputs on UI elements. See [method accept_event].
Replaces Godot 2's [code]_input_event[/code].
</description>
</method>
diff --git a/doc/classes/KinematicBody.xml b/doc/classes/KinematicBody.xml
index 0c66319ae7..17310ab4dc 100644
--- a/doc/classes/KinematicBody.xml
+++ b/doc/classes/KinematicBody.xml
@@ -115,6 +115,8 @@
<argument index="6" name="floor_max_angle" type="float" default="0.785398">
</argument>
<description>
+ Moves the body while keeping it attached to slopes. Similar to [method move_and_slide].
+ As long as the [code]snap[/code] vector is in contact with the ground, the body will remain attached to the surface. This means you must disable snap in order to jump, for example. You can do this by setting[code]snap[/code] to[code](0, 0, 0)[/code] or by using [method move_and_slide] instead.
</description>
</method>
<method name="test_move">
diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml
index d02e3dfdfa..dd496e79dd 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -50,7 +50,7 @@
<argument index="0" name="event" type="InputEvent">
</argument>
<description>
- Called when there is an input event. The input event propagates through the node tree until a node consumes it.
+ Called when there is an input event. The input event propagates up through the node tree until a node consumes it.
It is only called if input processing is enabled, which is done automatically if this method is overridden, and can be toggled with [method set_process_input].
To consume the input event and stop it propagating further to other nodes, [method SceneTree.set_input_as_handled] can be called.
For gameplay input, [method _unhandled_input] and [method _unhandled_key_input] are usually a better fit as they allow the GUI to intercept the events first.
@@ -93,7 +93,7 @@
<argument index="0" name="event" type="InputEvent">
</argument>
<description>
- Propagated to all nodes when the previous [InputEvent] is not consumed by any nodes.
+ Called when an [InputEvent] hasn't been consumed by [method _input] or any GUI. The input event propagates up through the node tree until a node consumes it.
It is only called if unhandled input processing is enabled, which is done automatically if this method is overridden, and can be toggled with [method set_process_unhandled_input].
To consume the input event and stop it propagating further to other nodes, [method SceneTree.set_input_as_handled] can be called.
For gameplay input, this and [method _unhandled_key_input] are usually a better fit than [method _input] as they allow the GUI to intercept the events first.
@@ -105,7 +105,7 @@
<argument index="0" name="event" type="InputEventKey">
</argument>
<description>
- Propagated to all nodes when the previous [InputEventKey] is not consumed by any nodes.
+ Called when an [InputEventKey] hasn't been consumed by [method _input] or any GUI. The input event propagates up through the node tree until a node consumes it.
It is only called if unhandled key input processing is enabled, which is done automatically if this method is overridden, and can be toggled with [method set_process_unhandled_key_input].
To consume the input event and stop it propagating further to other nodes, [method SceneTree.set_input_as_handled] can be called.
For gameplay input, this and [method _unhandled_input] are usually a better fit than [method _input] as they allow the GUI to intercept the events first.
diff --git a/doc/classes/PhysicsMaterial.xml b/doc/classes/PhysicsMaterial.xml
index bfebb472a5..3eebcc57a1 100644
--- a/doc/classes/PhysicsMaterial.xml
+++ b/doc/classes/PhysicsMaterial.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsMaterial" inherits="Resource" category="Core" version="3.1">
<brief_description>
+ A material for physics properties.
</brief_description>
<description>
+ Provides a means of modifying the collision properties of a [PhysicsBody].
</description>
<tutorials>
</tutorials>
@@ -14,8 +16,10 @@
<member name="absorbent" type="bool" setter="set_absorbent" getter="is_absorbent">
</member>
<member name="bounce" type="float" setter="set_bounce" getter="get_bounce">
+ The body's bounciness. Default value: [code]0[/code].
</member>
<member name="friction" type="float" setter="set_friction" getter="get_friction">
+ The body's friction. Values range from [code]0[/code] (frictionless) to [code]1[/code] (maximum friction). Default value: [code]1[/code].
</member>
<member name="rough" type="bool" setter="set_rough" getter="is_rough">
</member>
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 358b7292a5..5f828550b9 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -658,6 +658,9 @@
</member>
<member name="rendering/quality/driver/driver_name" type="String" setter="" getter="">
</member>
+ <member name="rendering/quality/driver/driver_fallback" type="String" setter="" getter="">
+ Whether to allow falling back to other graphics drivers if the preferred driver is not available. Best means use the best working driver (this is the default). Never means never fall back to another driver even if it does not work. This means the project will not run if the preferred driver does not function.
+ </member>
<member name="rendering/quality/filters/anisotropic_filter_level" type="int" setter="" getter="">
Maximum Anisotropic filter level used for textures when anisotropy enabled.
</member>
diff --git a/doc/classes/UndoRedo.xml b/doc/classes/UndoRedo.xml
index b9550c17fb..0ea5c6e005 100644..100755
--- a/doc/classes/UndoRedo.xml
+++ b/doc/classes/UndoRedo.xml
@@ -4,8 +4,29 @@
Helper to manage UndoRedo in the editor or custom tools.
</brief_description>
<description>
- Helper to manage UndoRedo in the editor or custom tools. It works by storing calls to functions in both 'do' an 'undo' lists.
+ Helper to manage UndoRedo in the editor or custom tools. It works by registering methods and property changes inside 'actions'.
Common behavior is to create an action, then add do/undo calls to functions or property changes, then committing the action.
+ Here's an example on how to add an action to Godot editor's own 'undoredo':
+ [codeblock]
+ var undoredo = get_undo_redo() # method of EditorPlugin
+
+ func do_something():
+ pass # put your code here
+
+ func undo_something():
+ pass # put here the code that reverts what's done by "do_something()"
+
+ func _on_MyButton_pressed():
+ var node = get_node("MyNode2D")
+ undoredo.create_action("Move the node")
+ undoredo.add_do_method(self, "do_something")
+ undoredo.add_undo_method(self, "undo_something")
+ undoredo.add_do_property(node, "position", Vector2(100,100))
+ undoredo.add_undo_property(node, "position", node.position)
+ undoredo.commit_action()
+ [/codeblock]
+ [method create_action], [method add_do_method], [method add_undo_method], [method add_do_property], [method add_undo_property], and [method commit_action] should be called one after the other, like in the example. Not doing so could lead to crashes.
+ If you don't need to register a method you can leave [method add_do_method] and [method add_undo_method] out, and so it goes for properties. You can register more than one method/property.
</description>
<tutorials>
</tutorials>
@@ -20,6 +41,7 @@
<argument index="1" name="method" type="String">
</argument>
<description>
+ Register a method that will be called when the action is committed.
</description>
</method>
<method name="add_do_property">
@@ -32,7 +54,7 @@
<argument index="2" name="value" type="Variant">
</argument>
<description>
- Set a property with a custom value.
+ Register a property value change for 'do'.
</description>
</method>
<method name="add_do_reference">
@@ -41,7 +63,7 @@
<argument index="0" name="object" type="Object">
</argument>
<description>
- Add a 'do' reference that will be erased if the 'do' history is lost. This is useful mostly for new nodes created for the 'do' call. Do not use for resources.
+ Register a reference for 'do' that will be erased if the 'do' history is lost. This is useful mostly for new nodes created for the 'do' call. Do not use for resources.
</description>
</method>
<method name="add_undo_method" qualifiers="vararg">
@@ -52,6 +74,7 @@
<argument index="1" name="method" type="String">
</argument>
<description>
+ Register a method that will be called when the action is undone.
</description>
</method>
<method name="add_undo_property">
@@ -64,7 +87,7 @@
<argument index="2" name="value" type="Variant">
</argument>
<description>
- Undo setting of a property with a custom value.
+ Register a property value change for 'undo'.
</description>
</method>
<method name="add_undo_reference">
@@ -73,7 +96,7 @@
<argument index="0" name="object" type="Object">
</argument>
<description>
- Add an 'undo' reference that will be erased if the 'undo' history is lost. This is useful mostly for nodes removed with the 'do' call (not the 'undo' call!).
+ Register a reference for 'undo' that will be erased if the 'undo' history is lost. This is useful mostly for nodes removed with the 'do' call (not the 'undo' call!).
</description>
</method>
<method name="clear_history">
@@ -98,7 +121,7 @@
<argument index="1" name="merge_mode" type="int" enum="UndoRedo.MergeMode" default="0">
</argument>
<description>
- Create a new action. After this is called, do all your calls to [method add_do_method], [method add_undo_method], [method add_do_property] and [method add_undo_property].
+ Create a new action. After this is called, do all your calls to [method add_do_method], [method add_undo_method], [method add_do_property], and [method add_undo_property], then commit the action with [method commit_action].
</description>
</method>
<method name="get_current_action_name" qualifiers="const">
@@ -120,12 +143,14 @@
<return type="bool">
</return>
<description>
+ Redo last action.
</description>
</method>
<method name="undo">
<return type="bool">
</return>
<description>
+ Undo last action.
</description>
</method>
</methods>
diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml
index 4bc18b926e..a721ef50c5 100644
--- a/doc/classes/Vector2.xml
+++ b/doc/classes/Vector2.xml
@@ -109,7 +109,7 @@
<argument index="3" name="t" type="float">
</argument>
<description>
- Cubicly interpolates between this vector and [code]b[/code] using [code]pre_a[/code] and [code]post_b[/code] as handles, and returns the result at position [code]t[/code]. [code]t[/code] is in the range of [code]0.0 - 1.0[/code], or a percentage of how far along the interpolation is.
+ Cubicly interpolates between this vector and [code]b[/code] using [code]pre_a[/code] and [code]post_b[/code] as handles, and returns the result at position [code]t[/code]. [code]t[/code] is in the range of [code]0.0 - 1.0[/code], representing the amount of interpolation.
</description>
</method>
<method name="distance_squared_to">
@@ -175,7 +175,7 @@
<argument index="1" name="t" type="float">
</argument>
<description>
- Returns the result of the linear interpolation between this vector and [code]b[/code] by amount [code]t[/code]. [code]t[/code] is in the range of [code]0.0 - 1.0[/code], a percentage of how far along the interpolation is.
+ Returns the result of the linear interpolation between this vector and [code]b[/code] by amount [code]t[/code]. [code]t[/code] is in the range of [code]0.0 - 1.0[/code], representing the amount of interpolation.
</description>
</method>
<method name="normalized">
@@ -227,7 +227,7 @@
<argument index="1" name="t" type="float">
</argument>
<description>
- Returns the result of SLERP between this vector and "b", by amount "t". "t" should be a float of 0.0-1.0, a percentage of how far along the interpolation is.
+ Returns the result of SLERP between this vector and [code]b[/code], by amount [code]t[/code]. [code]t[/code] is in the range of [code]0.0 - 1.0[/code], representing the amount of interpolation.
Both vectors need to be normalized.
</description>
</method>
@@ -267,16 +267,22 @@
</members>
<constants>
<constant name="ZERO" value="Vector2( 0, 0 )">
+ Null vector.
</constant>
<constant name="INF" value="Vector2( inf, inf )">
+ Infinite vector.
</constant>
<constant name="LEFT" value="Vector2( -1, 0 )">
+ Left unit vector.
</constant>
<constant name="RIGHT" value="Vector2( 1, 0 )">
+ Right unit vector.
</constant>
<constant name="UP" value="Vector2( 0, -1 )">
+ Up unit vector.
</constant>
<constant name="DOWN" value="Vector2( 0, 1 )">
+ Down unit vector.
</constant>
</constants>
</class>
diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml
index b4dcc6c6aa..4211c34d8e 100644
--- a/doc/classes/Vector3.xml
+++ b/doc/classes/Vector3.xml
@@ -78,7 +78,7 @@
<argument index="3" name="t" type="float">
</argument>
<description>
- Performs a cubic interpolation between vectors [code]pre_a[/code], [code]a[/code], [code]b[/code], [code]post_b[/code] ([code]a[/code] is current), by the given amount (t). (t) should be a float of 0.0-1.0, a percentage of how far along the interpolation is.
+ Performs a cubic interpolation between vectors [code]pre_a[/code], [code]a[/code], [code]b[/code], [code]post_b[/code] ([code]a[/code] is current), by the given amount [code]t[/code]. [code]t[/code] is in the range of [code]0.0 - 1.0[/code], representing the amount of interpolation.
</description>
</method>
<method name="distance_squared_to">
@@ -151,7 +151,7 @@
<argument index="1" name="t" type="float">
</argument>
<description>
- Returns the result of the linear interpolation between this vector and [code]b[/code] by amount [code]t[/code]. [code]t[/code] is in the range of [code]0.0 - 1.0[/code], a percentage of how far along the interpolation is.
+ Returns the result of the linear interpolation between this vector and [code]b[/code] by amount [code]t[/code]. [code]t[/code] is in the range of [code]0.0 - 1.0[/code], representing the amount of interpolation..
</description>
</method>
<method name="max_axis">
@@ -228,7 +228,7 @@
<argument index="1" name="t" type="float">
</argument>
<description>
- Returns the result of SLERP between this vector and "b", by amount "t". "t" should be a float of 0.0-1.0, a percentage of how far along the interpolation is.
+ Returns the result of SLERP between this vector and [code]b[/code], by amount [code]t[/code]. [code]t[/code] is in the range of [code]0.0 - 1.0[/code], representing the amount of interpolation.
Both vectors need to be normalized.
</description>
</method>
@@ -280,20 +280,28 @@
Enumerated value for the Z axis.
</constant>
<constant name="ZERO" value="Vector3( 0, 0, 0 )">
+ Null vector.
</constant>
<constant name="INF" value="Vector3( inf, inf, inf )">
+ Infinite vector.
</constant>
<constant name="LEFT" value="Vector3( -1, 0, 0 )">
+ Left unit vector.
</constant>
<constant name="RIGHT" value="Vector3( 1, 0, 0 )">
+ Right unit vector.
</constant>
<constant name="UP" value="Vector3( 0, 1, 0 )">
+ Up unit vector.
</constant>
<constant name="DOWN" value="Vector3( 0, -1, 0 )">
+ Down unit vector.
</constant>
<constant name="FORWARD" value="Vector3( 0, 0, -1 )">
+ Forward unit vector.
</constant>
<constant name="BACK" value="Vector3( 0, 0, 1 )">
+ Back unit vector.
</constant>
</constants>
</class>
diff --git a/doc/classes/VideoStream.xml b/doc/classes/VideoStream.xml
index 6bfa48511b..9f2655ed1b 100644
--- a/doc/classes/VideoStream.xml
+++ b/doc/classes/VideoStream.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VideoStream" inherits="Resource" category="Core" version="3.1">
<brief_description>
+ Base resource for video streams.
</brief_description>
<description>
</description>
diff --git a/doc/classes/ViewportContainer.xml b/doc/classes/ViewportContainer.xml
index 8c60fb473d..dde429440d 100644
--- a/doc/classes/ViewportContainer.xml
+++ b/doc/classes/ViewportContainer.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ViewportContainer" inherits="Container" category="Core" version="3.1">
<brief_description>
+ Control for holding [Viewport]s.
</brief_description>
<description>
+ A [Container] node that holds a [Viewport], automatically setting its size.
</description>
<tutorials>
</tutorials>
@@ -12,6 +14,7 @@
</methods>
<members>
<member name="stretch" type="bool" setter="set_stretch" getter="is_stretch_enabled">
+ If [code]true[/code] the viewport will be scaled to the control's size. Default value:[code]false[/code].
</member>
<member name="stretch_shrink" type="int" setter="set_stretch_shrink" getter="get_stretch_shrink">
</member>
diff --git a/doc/classes/WindowDialog.xml b/doc/classes/WindowDialog.xml
index 39487f5020..f7f2d10fcd 100644
--- a/doc/classes/WindowDialog.xml
+++ b/doc/classes/WindowDialog.xml
@@ -24,7 +24,7 @@
If [code]true[/code] the user can resize the window. Default value: [code]false[/code].
</member>
<member name="window_title" type="String" setter="set_title" getter="get_title">
- The text displayed in the window's title bar. Default value: "Save a File".
+ The text displayed in the window's title bar.
</member>
</members>
<constants>
diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h
index e39ec915fc..0381d3f0c1 100644
--- a/drivers/dummy/rasterizer_dummy.h
+++ b/drivers/dummy/rasterizer_dummy.h
@@ -789,6 +789,10 @@ public:
void end_frame(bool p_swap_buffers) {}
void finalize() {}
+ static Error is_viable() {
+ return OK;
+ }
+
static Rasterizer *_create_current() {
return memnew(RasterizerDummy);
}
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index c926f2bcc4..76ee80aa07 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -136,26 +136,21 @@ RasterizerScene *RasterizerGLES2::get_scene() {
return scene;
}
-void RasterizerGLES2::initialize() {
-
- print_verbose("Using GLES2 video driver");
+Error RasterizerGLES2::is_viable() {
#ifdef GLAD_ENABLED
if (!gladLoadGL()) {
ERR_PRINT("Error initializing GLAD");
+ return ERR_UNAVAILABLE;
}
// GLVersion seems to be used for both GL and GL ES, so we need different version checks for them
#ifdef OPENGL_ENABLED // OpenGL 2.1 Profile required
- if (GLVersion.major < 2) {
-#else // OpenGL ES 3.0
+ if (GLVersion.major < 2 || (GLVersion.major == 2 && GLVersion.minor < 1)) {
+#else // OpenGL ES 2.0
if (GLVersion.major < 2) {
#endif
- ERR_PRINT("Your system's graphic drivers seem not to support OpenGL 2.1 / OpenGL ES 2.0, sorry :(\n"
- "Try a drivers update, buy a new GPU or try software rendering on Linux; Godot will now crash with a segmentation fault.");
- OS::get_singleton()->alert("Your system's graphic drivers seem not to support OpenGL 2.1 / OpenGL ES 2.0, sorry :(\n"
- "Godot Engine will self-destruct as soon as you acknowledge this error message.",
- "Fatal error: Insufficient OpenGL / GLES driver support");
+ return ERR_UNAVAILABLE;
}
#ifdef GLES_OVER_GL
@@ -181,14 +176,21 @@ void RasterizerGLES2::initialize() {
glGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameterivEXT;
glGenerateMipmap = glGenerateMipmapEXT;
} else {
- ERR_PRINT("Your system's graphic drivers seem not to support GL_ARB(EXT)_framebuffer_object OpenGL extension, sorry :(\n"
- "Try a drivers update, buy a new GPU or try software rendering on Linux; Godot will now crash with a segmentation fault.");
- OS::get_singleton()->alert("Your system's graphic drivers seem not to support GL_ARB(EXT)_framebuffer_object OpenGL extension, sorry :(\n"
- "Godot Engine will self-destruct as soon as you acknowledge this error message.",
- "Fatal error: Insufficient OpenGL / GLES driver support");
+ return ERR_UNAVAILABLE;
}
}
#endif
+
+#endif // GLAD_ENABLED
+
+ return OK;
+}
+
+void RasterizerGLES2::initialize() {
+
+ print_verbose("Using GLES2 video driver");
+
+#ifdef GLAD_ENABLED
if (true || OS::get_singleton()->is_stdout_verbose()) {
if (GLAD_GL_ARB_debug_output) {
glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
@@ -198,7 +200,6 @@ void RasterizerGLES2::initialize() {
print_line("OpenGL debugging not supported!");
}
}
-
#endif // GLAD_ENABLED
// For debugging
diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h
index f727af39dd..98c73b776b 100644
--- a/drivers/gles2/rasterizer_gles2.h
+++ b/drivers/gles2/rasterizer_gles2.h
@@ -61,9 +61,10 @@ public:
virtual void end_frame(bool p_swap_buffers);
virtual void finalize();
+ static Error is_viable();
static void make_current();
-
static void register_config();
+
RasterizerGLES2();
~RasterizerGLES2();
};
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index 22e56fbb09..3cee42983d 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -365,7 +365,6 @@ void RasterizerStorageGLES2::texture_allocate(RID p_texture, int p_width, int p_
ERR_FAIL_COND(!texture);
texture->width = p_width;
texture->height = p_height;
- texture->depth = 0;
texture->format = p_format;
texture->flags = p_flags;
texture->stored_cube_sides = 0;
@@ -385,7 +384,6 @@ void RasterizerStorageGLES2::texture_allocate(RID p_texture, int p_width, int p_
} break;
case VS::TEXTURE_TYPE_3D: {
texture->images.resize(p_depth_3d);
- texture->depth = p_depth_3d;
} break;
default: {
ERR_PRINT("Unknown texture type!");
@@ -398,7 +396,6 @@ void RasterizerStorageGLES2::texture_allocate(RID p_texture, int p_width, int p_
texture->alloc_width = texture->width;
texture->alloc_height = texture->height;
- texture->alloc_depth = texture->depth;
texture->gl_format_cache = format;
texture->gl_type_cache = type;
@@ -594,9 +591,7 @@ Ref<Image> RasterizerStorageGLES2::texture_get_data(RID p_texture, int p_layer)
PoolVector<uint8_t> data;
- int alloc_depth = MAX(texture->alloc_depth, 1);
-
- int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, real_format, texture->mipmaps > 1 ? -1 : 0) * alloc_depth;
+ int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, real_format, texture->mipmaps > 1 ? -1 : 0);
data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers
PoolVector<uint8_t>::Write wb = data.write();
@@ -625,7 +620,7 @@ Ref<Image> RasterizerStorageGLES2::texture_get_data(RID p_texture, int p_layer)
wb = PoolVector<uint8_t>::Write();
- data.resize(data_size / alloc_depth);
+ data.resize(data_size);
Image *img = memnew(Image(texture->alloc_width, texture->alloc_height, texture->mipmaps > 1 ? true : false, real_format, data));
@@ -785,7 +780,7 @@ void RasterizerStorageGLES2::texture_debug_usage(List<VS::TextureInfo> *r_info)
tinfo.format = t->format;
tinfo.width = t->alloc_width;
tinfo.height = t->alloc_height;
- tinfo.depth = t->alloc_depth;
+ tinfo.depth = 0;
tinfo.bytes = t->total_data_size;
r_info->push_back(tinfo);
}
@@ -3667,8 +3662,6 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
texture->alloc_width = rt->width;
texture->height = rt->height;
texture->alloc_height = rt->height;
- texture->depth = 0;
- texture->alloc_depth = 0;
texture->active = true;
texture_set_flags(rt->texture, texture->flags);
@@ -3716,8 +3709,6 @@ void RasterizerStorageGLES2::_render_target_clear(RenderTarget *rt) {
Texture *tex = texture_owner.get(rt->texture);
tex->alloc_height = 0;
tex->alloc_width = 0;
- tex->alloc_depth = 0;
- tex->depth = 0;
tex->width = 0;
tex->height = 0;
tex->active = false;
@@ -3741,10 +3732,8 @@ RID RasterizerStorageGLES2::render_target_create() {
t->flags = 0;
t->width = 0;
t->height = 0;
- t->depth = 0;
- t->alloc_width = 0;
t->alloc_height = 0;
- t->alloc_depth = 0;
+ t->alloc_width = 0;
t->format = Image::FORMAT_R8;
t->target = GL_TEXTURE_2D;
t->gl_format_cache = 0;
diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h
index c3066b754d..88783d7160 100644
--- a/drivers/gles2/rasterizer_storage_gles2.h
+++ b/drivers/gles2/rasterizer_storage_gles2.h
@@ -232,7 +232,7 @@ public:
String path;
uint32_t flags;
int width, height, depth;
- int alloc_width, alloc_height, alloc_depth;
+ int alloc_width, alloc_height;
Image::Format format;
VS::TextureType type;
@@ -275,10 +275,8 @@ public:
flags = 0;
width = 0;
height = 0;
- depth = 0;
alloc_width = 0;
alloc_height = 0;
- alloc_depth = 0;
format = Image::FORMAT_L8;
target = 0;
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index 0d42635194..e4824695d5 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -136,28 +136,32 @@ typedef void (*DEBUGPROCARB)(GLenum source,
typedef void (*DebugMessageCallbackARB)(DEBUGPROCARB callback, const void *userParam);
-void RasterizerGLES3::initialize() {
-
- print_verbose("Using GLES3 video driver");
+Error RasterizerGLES3::is_viable() {
#ifdef GLAD_ENABLED
if (!gladLoadGL()) {
ERR_PRINT("Error initializing GLAD");
+ return ERR_UNAVAILABLE;
}
// GLVersion seems to be used for both GL and GL ES, so we need different version checks for them
#ifdef OPENGL_ENABLED // OpenGL 3.3 Core Profile required
- if (GLVersion.major < 3 && GLVersion.minor < 3) {
+ if (GLVersion.major < 3 || (GLVersion.major == 3 && GLVersion.minor < 3)) {
#else // OpenGL ES 3.0
if (GLVersion.major < 3) {
#endif
- ERR_PRINT("Your system's graphic drivers seem not to support OpenGL 3.3 / OpenGL ES 3.0, sorry :(\n"
- "Try a drivers update, buy a new GPU or try software rendering on Linux; Godot will now crash with a segmentation fault.");
- OS::get_singleton()->alert("Your system's graphic drivers seem not to support OpenGL 3.3 / OpenGL ES 3.0, sorry :(\n"
- "Godot Engine will self-destruct as soon as you acknowledge this error message.",
- "Fatal error: Insufficient OpenGL / GLES driver support");
+ return ERR_UNAVAILABLE;
}
+#endif // GLAD_ENABLED
+ return OK;
+}
+
+void RasterizerGLES3::initialize() {
+
+ print_verbose("Using GLES3 video driver");
+
+#ifdef GLAD_ENABLED
if (OS::get_singleton()->is_stdout_verbose()) {
if (GLAD_GL_ARB_debug_output) {
glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
@@ -167,7 +171,6 @@ void RasterizerGLES3::initialize() {
print_line("OpenGL debugging not supported!");
}
}
-
#endif // GLAD_ENABLED
/* // For debugging
diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h
index f4449ac0f9..0a264caf8f 100644
--- a/drivers/gles3/rasterizer_gles3.h
+++ b/drivers/gles3/rasterizer_gles3.h
@@ -62,9 +62,10 @@ public:
virtual void end_frame(bool p_swap_buffers);
virtual void finalize();
+ static Error is_viable();
static void make_current();
-
static void register_config();
+
RasterizerGLES3();
~RasterizerGLES3();
};
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 5ee6c28d83..0bb0e12b8e 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -667,7 +667,7 @@ void RasterizerStorageGLES3::texture_allocate(RID p_texture, int p_width, int p_
int mipmaps = 0;
while (width != 1 && height != 1) {
- glTexImage3D(texture->target, mipmaps, internal_format, width, height, depth, 0, format, type, NULL);
+ glTexImage3D(texture->target, 0, internal_format, width, height, depth, 0, format, type, NULL);
width = MAX(1, width / 2);
height = MAX(1, height / 2);
@@ -1029,11 +1029,7 @@ Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, int p_layer)
PoolVector<uint8_t> data;
- int alloc_depth = MAX(texture->alloc_depth, 1);
-
- ERR_FAIL_COND_V(p_layer < 0 || p_layer >= alloc_depth, Ref<Image>());
-
- int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, real_format, texture->mipmaps > 1 ? -1 : 0) * alloc_depth;
+ int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, real_format, texture->mipmaps > 1 ? -1 : 0);
data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers
PoolVector<uint8_t>::Write wb = data.write();
@@ -1089,13 +1085,9 @@ Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, int p_layer)
img_format = real_format;
}
- int slice_size = data_size / alloc_depth;
-
- if (p_layer) {
- memcpy(&wb[0], &wb[slice_size * p_layer], slice_size);
- }
+ wb = PoolVector<uint8_t>::Write();
- data.resize(slice_size);
+ data.resize(data_size);
Image *img = memnew(Image(texture->alloc_width, texture->alloc_height, texture->mipmaps > 1 ? true : false, img_format, data));
@@ -1283,7 +1275,7 @@ void RasterizerStorageGLES3::texture_debug_usage(List<VS::TextureInfo> *r_info)
tinfo.format = t->format;
tinfo.width = t->alloc_width;
tinfo.height = t->alloc_height;
- tinfo.depth = t->alloc_depth;
+ tinfo.depth = 0;
tinfo.bytes = t->total_data_size;
r_info->push_back(tinfo);
}
@@ -1450,7 +1442,6 @@ RID RasterizerStorageGLES3::texture_create_radiance_cubemap(RID p_source, int p_
ctex->height = p_resolution;
ctex->alloc_width = p_resolution;
ctex->alloc_height = p_resolution;
- ctex->alloc_depth = 0;
ctex->format = use_float ? Image::FORMAT_RGBAH : Image::FORMAT_RGBA8;
ctex->target = GL_TEXTURE_CUBE_MAP;
ctex->gl_format_cache = format;
@@ -6473,7 +6464,6 @@ void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) {
Texture *tex = texture_owner.get(rt->texture);
tex->alloc_height = 0;
tex->alloc_width = 0;
- tex->alloc_depth = 0;
tex->width = 0;
tex->height = 0;
tex->active = false;
@@ -6587,7 +6577,6 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
tex->height = rt->height;
tex->alloc_height = rt->height;
tex->active = true;
- tex->alloc_depth = 0;
texture_set_flags(rt->texture, tex->flags);
}
@@ -6876,10 +6865,8 @@ RID RasterizerStorageGLES3::render_target_create() {
t->flags = 0;
t->width = 0;
t->height = 0;
- t->depth = 0;
t->alloc_height = 0;
t->alloc_width = 0;
- t->alloc_depth = 0;
t->format = Image::FORMAT_R8;
t->target = GL_TEXTURE_2D;
t->gl_format_cache = 0;
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 43b7d5fc99..b74dd77e26 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -294,13 +294,7 @@ public:
stored_cube_sides = 0;
ignore_mipmaps = false;
render_target = NULL;
- flags = 0;
- width = 0;
- height = 0;
- depth = 0;
- alloc_width = 0;
- alloc_height = 0;
- alloc_depth = 0;
+ flags = width = height = 0;
tex_id = 0;
data_size = 0;
format = Image::FORMAT_L8;
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index 8aab4cb521..05dfd69f58 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -329,7 +329,7 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo
return OK;
}
-Error OS_Unix::kill(const ProcessID &p_pid, const int p_max_wait_msec) {
+Error OS_Unix::kill(const ProcessID &p_pid) {
int ret = ::kill(p_pid, SIGKILL);
if (!ret) {
diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h
index c5240231fa..95b74d23ff 100644
--- a/drivers/unix/os_unix.h
+++ b/drivers/unix/os_unix.h
@@ -91,7 +91,7 @@ public:
virtual uint64_t get_ticks_usec() const;
virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false);
- virtual Error kill(const ProcessID &p_pid, const int p_max_wait_msec = -1);
+ virtual Error kill(const ProcessID &p_pid);
virtual int get_process_id() const;
virtual bool has_environment(const String &p_var) const;
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index e46fe96885..441c09620e 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -667,7 +667,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
String remap = F->get();
String feature = remap.get_slice(".", 1);
- if (feature == "fallback" || features.has(feature)) {
+ if (features.has(feature)) {
remap_features.insert(feature);
}
}
@@ -1457,7 +1457,6 @@ void EditorExportPlatformPC::resolve_platform_feature_priorities(const Ref<Edito
if (p_features.has("bptc")) {
if (p_preset->has("texture_format/no_bptc_fallbacks")) {
p_features.erase("s3tc");
- p_features.erase("fallback");
}
}
}
diff --git a/editor/editor_profiler.cpp b/editor/editor_profiler.cpp
index f57c863bcf..223bb9df84 100644
--- a/editor/editor_profiler.cpp
+++ b/editor/editor_profiler.cpp
@@ -100,8 +100,6 @@ void EditorProfiler::clear() {
updating_frame = false;
hover_metric = -1;
seeking = false;
-
- _update_plot();
}
static String _get_percent_txt(float p_value, float p_total) {
@@ -169,7 +167,7 @@ void EditorProfiler::_update_plot() {
int w = graph->get_size().width;
int h = graph->get_size().height;
- bool reset_texture = graph_texture.is_null();
+ bool reset_texture = false;
int desired_len = w * h * 4;
@@ -437,6 +435,7 @@ void EditorProfiler::_activate_pressed() {
void EditorProfiler::_clear_pressed() {
clear();
+ _update_plot();
}
void EditorProfiler::_notification(int p_what) {
diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp
index bbd18306a2..62870ab35c 100644
--- a/editor/editor_run.cpp
+++ b/editor/editor_run.cpp
@@ -196,8 +196,8 @@ Error EditorRun::run(const String &p_scene, const String p_custom_args, const Li
void EditorRun::stop() {
if (status != STATUS_STOP && pid != 0) {
- const int max_wait_msec = GLOBAL_DEF("editor/stop_max_wait_msec", 10000);
- OS::get_singleton()->kill(pid, max_wait_msec);
+
+ OS::get_singleton()->kill(pid);
}
status = STATUS_STOP;
diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp
index 4d5c292847..3d3dc978bc 100644
--- a/editor/import/editor_scene_importer_gltf.cpp
+++ b/editor/import/editor_scene_importer_gltf.cpp
@@ -793,7 +793,7 @@ Vector<Quat> EditorSceneImporterGLTF::_decode_accessor_as_quat(GLTFState &state,
ret.resize(ret_size);
{
for (int i = 0; i < ret_size; i++) {
- ret.write[i] = Quat(attribs_ptr[i * 4 + 0], attribs_ptr[i * 4 + 1], attribs_ptr[i * 4 + 2], attribs_ptr[i * 4 + 3]);
+ ret.write[i] = Quat(attribs_ptr[i * 4 + 0], attribs_ptr[i * 4 + 1], attribs_ptr[i * 4 + 2], attribs_ptr[i * 4 + 3]).normalized();
}
}
return ret;
@@ -1793,17 +1793,24 @@ template <>
struct EditorSceneImporterGLTFInterpolate<Quat> {
Quat lerp(const Quat &a, const Quat &b, float c) const {
+ ERR_FAIL_COND_V(a.is_normalized() == false, Quat());
+ ERR_FAIL_COND_V(b.is_normalized() == false, Quat());
- return a.slerp(b, c);
+ return a.slerp(b, c).normalized();
}
Quat catmull_rom(const Quat &p0, const Quat &p1, const Quat &p2, const Quat &p3, float c) {
+ ERR_FAIL_COND_V(p1.is_normalized() == false, Quat());
+ ERR_FAIL_COND_V(p2.is_normalized() == false, Quat());
- return p1.slerp(p2, c);
+ return p1.slerp(p2, c).normalized();
}
Quat bezier(Quat start, Quat control_1, Quat control_2, Quat end, float t) {
- return start.slerp(end, t);
+ ERR_FAIL_COND_V(start.is_normalized() == false, Quat());
+ ERR_FAIL_COND_V(end.is_normalized() == false, Quat());
+
+ return start.slerp(end, t).normalized();
}
};
@@ -1945,7 +1952,7 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye
Vector3 base_scale = Vector3(1, 1, 1);
if (!track.rotation_track.values.size()) {
- base_rot = state.nodes[E->key()]->rotation;
+ base_rot = state.nodes[E->key()]->rotation.normalized();
}
if (!track.translation_track.values.size()) {
@@ -1991,6 +1998,7 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye
xform = skeleton->get_bone_rest(bone).affine_inverse() * xform;
rot = xform.basis.get_rotation_quat();
+ rot.normalize();
scale = xform.basis.get_scale();
pos = xform.origin;
}
diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp
index d03395c070..846286c74b 100644
--- a/editor/import/resource_importer_texture.cpp
+++ b/editor/import/resource_importer_texture.cpp
@@ -164,7 +164,7 @@ bool ResourceImporterTexture::get_option_visibility(const String &p_option, cons
if (compress_mode != COMPRESS_LOSSY && compress_mode != COMPRESS_VIDEO_RAM) {
return false;
}
- } else if (p_option == "compress/no_bptc_if_rgb" || p_option == "compress/hdr_mode") {
+ } else if (p_option == "compress/hdr_mode") {
int compress_mode = int(p_options["compress/mode"]);
if (compress_mode != COMPRESS_VIDEO_RAM) {
return false;
@@ -193,8 +193,7 @@ void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options,
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Lossless,Lossy,Video RAM,Uncompressed", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), p_preset == PRESET_3D ? 2 : 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "compress/lossy_quality", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.7));
- r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress/no_bptc_if_rgb"), false));
- r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/hdr_mode", PROPERTY_HINT_ENUM, "LDR Fallback,Force RGBE,RGBE Fallback"), 0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/hdr_mode", PROPERTY_HINT_ENUM, "Enabled,Force RGBE"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/normal_map", PROPERTY_HINT_ENUM, "Detect,Enable,Disabled"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "flags/repeat", PROPERTY_HINT_ENUM, "Disabled,Enabled,Mirrored"), p_preset == PRESET_3D ? 1 : 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "flags/filter"), p_preset == PRESET_2D_PIXEL ? false : true));
@@ -353,7 +352,6 @@ void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String
Error ResourceImporterTexture::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) {
int compress_mode = p_options["compress/mode"];
- int no_bptc_if_rgb = p_options["compress/no_bptc_if_rgb"];
float lossy = p_options["compress/lossy_quality"];
int repeat = p_options["flags/repeat"];
bool filter = p_options["flags/filter"];
@@ -365,11 +363,10 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
bool invert_color = p_options["process/invert_color"];
bool stream = p_options["stream"];
int size_limit = p_options["size_limit"];
- bool force_rgbe = int(p_options["compress/hdr_mode"]) == 1;
- bool rgbe_fallback = int(p_options["compress/hdr_mode"]) == 2;
bool hdr_as_srgb = p_options["process/HDR_as_SRGB"];
int normal = p_options["compress/normal_map"];
float scale = p_options["svg/scale"];
+ bool force_rgbe = p_options["compress/hdr_mode"];
Ref<Image> image;
image.instance();
@@ -442,59 +439,40 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
//Android, GLES 2.x
bool ok_on_pc = false;
- bool encode_bptc = false;
- bool is_hdr = (image->get_format() >= Image::FORMAT_RF && image->get_format() <= Image::FORMAT_RGBE9995);
- bool no_ldr_compression = (is_hdr && rgbe_fallback);
+ bool can_bptc = (image->get_format() >= Image::FORMAT_RF && image->get_format() <= Image::FORMAT_RGBE9995);
- if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_bptc")) {
+ if (can_bptc) {
- encode_bptc = true;
-
- if (no_bptc_if_rgb && !is_hdr) {
- Image::DetectChannels channels = image->get_detected_channels();
- if (channels != Image::DETECTED_LA && channels != Image::DETECTED_RGBA) {
- encode_bptc = false;
- }
+ Image::DetectChannels channels = image->get_detected_channels();
+ if (channels != Image::DETECTED_LA && channels != Image::DETECTED_RGBA) {
+ can_bptc = false;
}
}
- if (encode_bptc) {
-
- _save_stex(image, p_save_path + ".bptc.stex", compress_mode, lossy, Image::COMPRESS_BPTC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal);
- r_platform_variants->push_back("bptc");
- ok_on_pc = true;
- }
+ if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_s3tc")) {
- if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_s3tc") && !no_ldr_compression) {
-
- _save_stex(image, p_save_path + ".s3tc.stex", compress_mode, lossy, Image::COMPRESS_S3TC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal);
+ _save_stex(image, p_save_path + ".s3tc.stex", compress_mode, lossy, can_bptc ? Image::COMPRESS_BPTC : Image::COMPRESS_S3TC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal);
r_platform_variants->push_back("s3tc");
ok_on_pc = true;
}
- if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2") && !no_ldr_compression) {
+ if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2")) {
_save_stex(image, p_save_path + ".etc2.stex", compress_mode, lossy, Image::COMPRESS_ETC2, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal);
r_platform_variants->push_back("etc2");
}
- if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc") && !no_ldr_compression) {
+ if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc")) {
_save_stex(image, p_save_path + ".etc.stex", compress_mode, lossy, Image::COMPRESS_ETC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal);
r_platform_variants->push_back("etc");
}
- if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc") && !no_ldr_compression) {
+ if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc")) {
_save_stex(image, p_save_path + ".pvrtc.stex", compress_mode, lossy, Image::COMPRESS_PVRTC4, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal);
r_platform_variants->push_back("pvrtc");
}
- if (is_hdr && rgbe_fallback) {
- _save_stex(image, p_save_path + ".fallback.stex", compress_mode, lossy, Image::COMPRESS_S3TC /*this is ignored */, mipmaps, tex_flags, stream, detect_3d, detect_srgb, true, detect_normal, force_normal);
- r_platform_variants->push_back("fallback");
- ok_on_pc = true;
- }
-
if (!ok_on_pc) {
EditorNode::add_io_error("Warning, no suitable PC VRAM compression enabled in Project Settings. This texture will not display correcly on PC.");
}
diff --git a/editor/plugins/item_list_editor_plugin.cpp b/editor/plugins/item_list_editor_plugin.cpp
index f75fb0d109..1f0b4e9e97 100644
--- a/editor/plugins/item_list_editor_plugin.cpp
+++ b/editor/plugins/item_list_editor_plugin.cpp
@@ -296,7 +296,7 @@ void ItemListEditor::_delete_pressed() {
void ItemListEditor::_edit_items() {
- dialog->popup_centered(Vector2(300, 400));
+ dialog->popup_centered(Vector2(300, 400) * EDSCALE);
}
void ItemListEditor::edit(Node *p_item_list) {
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 4e7047ee38..66705f85bf 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -1549,10 +1549,11 @@ void ScriptTextEditor::register_editor() {
ED_SHORTCUT("script_text_editor/unfold_all_lines", TTR("Unfold All Lines"), 0);
#ifdef OSX_ENABLED
ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_SHIFT | KEY_MASK_CMD | KEY_C);
+ ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CTRL | KEY_SPACE);
#else
ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_CMD | KEY_B);
-#endif
ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CMD | KEY_SPACE);
+#endif
ED_SHORTCUT("script_text_editor/trim_trailing_whitespace", TTR("Trim Trailing Whitespace"), KEY_MASK_CMD | KEY_MASK_ALT | KEY_T);
ED_SHORTCUT("script_text_editor/convert_indent_to_spaces", TTR("Convert Indent To Spaces"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Y);
ED_SHORTCUT("script_text_editor/convert_indent_to_tabs", TTR("Convert Indent To Tabs"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_X);
@@ -1575,15 +1576,20 @@ void ScriptTextEditor::register_editor() {
#ifdef OSX_ENABLED
ED_SHORTCUT("script_text_editor/find_next", TTR("Find Next"), KEY_MASK_CMD | KEY_G);
ED_SHORTCUT("script_text_editor/find_previous", TTR("Find Previous"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_G);
+ ED_SHORTCUT("script_text_editor/replace", TTR("Replace..."), KEY_MASK_ALT | KEY_MASK_CMD | KEY_F);
#else
ED_SHORTCUT("script_text_editor/find_next", TTR("Find Next"), KEY_F3);
ED_SHORTCUT("script_text_editor/find_previous", TTR("Find Previous"), KEY_MASK_SHIFT | KEY_F3);
-#endif
ED_SHORTCUT("script_text_editor/replace", TTR("Replace..."), KEY_MASK_CMD | KEY_R);
+#endif
ED_SHORTCUT("script_text_editor/find_in_files", TTR("Find in files..."), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F);
+#ifdef OSX_ENABLED
+ ED_SHORTCUT("script_text_editor/goto_function", TTR("Goto Function..."), KEY_MASK_CTRL | KEY_MASK_CMD | KEY_J);
+#else
ED_SHORTCUT("script_text_editor/goto_function", TTR("Goto Function..."), KEY_MASK_ALT | KEY_MASK_CMD | KEY_F);
+#endif
ED_SHORTCUT("script_text_editor/goto_line", TTR("Goto Line..."), KEY_MASK_CMD | KEY_L);
#ifdef OSX_ENABLED
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index ad4a2bdb22..cfc322d2c1 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -4465,6 +4465,7 @@ void SpatialEditor::_init_indicators() {
VisualServer::get_singleton()->instance_geometry_set_cast_shadows_setting(origin_instance, VS::SHADOW_CASTING_SETTING_OFF);
+ origin_enabled = true;
grid_enabled = true;
last_grid_snap = 1;
}
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index 34dd36692c..598f7034d8 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -457,36 +457,38 @@ void TileMapEditor::_update_palette() {
palette->select(0);
}
- if ((manual_autotile && tileset->tile_get_tile_mode(sel_tile) == TileSet::AUTO_TILE) || tileset->tile_get_tile_mode(sel_tile) == TileSet::ATLAS_TILE) {
+ if (sel_tile != TileMap::INVALID_CELL) {
+ if ((manual_autotile && tileset->tile_get_tile_mode(sel_tile) == TileSet::AUTO_TILE) || tileset->tile_get_tile_mode(sel_tile) == TileSet::ATLAS_TILE) {
- const Map<Vector2, uint16_t> &tiles = tileset->autotile_get_bitmask_map(sel_tile);
+ const Map<Vector2, uint16_t> &tiles = tileset->autotile_get_bitmask_map(sel_tile);
- Vector<Vector2> entries;
- for (const Map<Vector2, uint16_t>::Element *E = tiles.front(); E; E = E->next()) {
- entries.push_back(E->key());
- }
- entries.sort();
+ Vector<Vector2> entries;
+ for (const Map<Vector2, uint16_t>::Element *E = tiles.front(); E; E = E->next()) {
+ entries.push_back(E->key());
+ }
+ entries.sort();
- Ref<Texture> tex = tileset->tile_get_texture(sel_tile);
+ Ref<Texture> tex = tileset->tile_get_texture(sel_tile);
- for (int i = 0; i < entries.size(); i++) {
+ for (int i = 0; i < entries.size(); i++) {
- manual_palette->add_item(String());
+ manual_palette->add_item(String());
- if (tex.is_valid()) {
+ if (tex.is_valid()) {
- Rect2 region = tileset->tile_get_region(sel_tile);
- int spacing = tileset->autotile_get_spacing(sel_tile);
- region.size = tileset->autotile_get_size(sel_tile); // !!
- region.position += (region.size + Vector2(spacing, spacing)) * entries[i];
+ Rect2 region = tileset->tile_get_region(sel_tile);
+ int spacing = tileset->autotile_get_spacing(sel_tile);
+ region.size = tileset->autotile_get_size(sel_tile); // !!
+ region.position += (region.size + Vector2(spacing, spacing)) * entries[i];
- if (!region.has_no_area())
- manual_palette->set_item_icon_region(manual_palette->get_item_count() - 1, region);
+ if (!region.has_no_area())
+ manual_palette->set_item_icon_region(manual_palette->get_item_count() - 1, region);
- manual_palette->set_item_icon(manual_palette->get_item_count() - 1, tex);
- }
+ manual_palette->set_item_icon(manual_palette->get_item_count() - 1, tex);
+ }
- manual_palette->set_item_metadata(manual_palette->get_item_count() - 1, entries[i]);
+ manual_palette->set_item_metadata(manual_palette->get_item_count() - 1, entries[i]);
+ }
}
}
diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp
index 55a04a51b3..f981ead7eb 100644
--- a/editor/plugins/tile_set_editor_plugin.cpp
+++ b/editor/plugins/tile_set_editor_plugin.cpp
@@ -498,7 +498,7 @@ void TileSetEditor::_on_tileset_toolbar_button_pressed(int p_index) {
} break;
case TOOL_TILESET_REMOVE_TEXTURE: {
if (get_current_texture().is_valid()) {
- cd->set_text(TTR("Remove Selected Textue and ALL TILES wich uses it?"));
+ cd->set_text(TTR("Remove selected texture and ALL TILES which use it?"));
cd->popup_centered(Size2(300, 60));
} else {
err_dialog->set_text(TTR("You haven't selected a texture to remove."));
@@ -1715,16 +1715,18 @@ void TileSetEditor::draw_polygon_shapes() {
Vector<Vector2> polygon;
Vector<Color> colors;
+ Vector2 anchor = WORKSPACE_MARGIN;
+ anchor += tileset->tile_get_region(get_current_tile()).position;
for (int j = 0; j < shape->get_polygon().size(); j++) {
- polygon.push_back(shape->get_polygon()[j]);
+ polygon.push_back(shape->get_polygon()[j] + anchor);
colors.push_back(c_bg);
}
workspace->draw_polygon(polygon, colors);
for (int j = 0; j < shape->get_polygon().size() - 1; j++) {
- workspace->draw_line(shape->get_polygon()[j], shape->get_polygon()[j + 1], c_border, 1, true);
+ workspace->draw_line(shape->get_polygon()[j] + anchor, shape->get_polygon()[j + 1] + anchor, c_border, 1, true);
}
- workspace->draw_line(shape->get_polygon()[shape->get_polygon().size() - 1], shape->get_polygon()[0], c_border, 1, true);
+ workspace->draw_line(shape->get_polygon()[shape->get_polygon().size() - 1] + anchor, shape->get_polygon()[0] + anchor, c_border, 1, true);
if (shape == edited_occlusion_shape) {
draw_handles = true;
}
@@ -1788,10 +1790,11 @@ void TileSetEditor::draw_polygon_shapes() {
Vector<Vector2> polygon;
Vector<Color> colors;
-
+ Vector2 anchor = WORKSPACE_MARGIN;
+ anchor += tileset->tile_get_region(get_current_tile()).position;
PoolVector<Vector2> vertices = shape->get_vertices();
for (int j = 0; j < shape->get_polygon(0).size(); j++) {
- polygon.push_back(vertices[shape->get_polygon(0)[j]]);
+ polygon.push_back(vertices[shape->get_polygon(0)[j]] + anchor);
colors.push_back(c_bg);
}
workspace->draw_polygon(polygon, colors);
@@ -1799,7 +1802,7 @@ void TileSetEditor::draw_polygon_shapes() {
if (shape->get_polygon_count() > 0) {
PoolVector<Vector2> vertices = shape->get_vertices();
for (int j = 0; j < shape->get_polygon(0).size() - 1; j++) {
- workspace->draw_line(vertices[shape->get_polygon(0)[j]], vertices[shape->get_polygon(0)[j + 1]], c_border, 1, true);
+ workspace->draw_line(vertices[shape->get_polygon(0)[j]] + anchor, vertices[shape->get_polygon(0)[j + 1]] + anchor, c_border, 1, true);
}
if (shape == edited_navigation_shape) {
draw_handles = true;
@@ -1954,6 +1957,8 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) {
void TileSetEditor::select_coord(const Vector2 &coord) {
current_shape = PoolVector2Array();
+ if (get_current_tile() == -1)
+ return;
Rect2 current_tile_region = tileset->tile_get_region(get_current_tile());
current_tile_region.position += WORKSPACE_MARGIN;
if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE) {
@@ -2038,8 +2043,10 @@ Vector2 TileSetEditor::snap_point(const Vector2 &point) {
anchor += tileset->tile_get_region(get_current_tile()).position;
anchor += WORKSPACE_MARGIN;
Rect2 region(anchor, tile_size);
- if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE)
+ if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE) {
region.position = tileset->tile_get_region(get_current_tile()).position + WORKSPACE_MARGIN;
+ region.size = tileset->tile_get_region(get_current_tile()).size;
+ }
if (tools[TOOL_GRID_SNAP]->is_pressed()) {
p.x = Math::snap_scalar_seperation(snap_offset.x, snap_step.x, p.x, snap_separation.x);
@@ -2254,6 +2261,9 @@ bool TilesetEditorContext::_set(const StringName &p_name, const Variant &p_value
tileset_editor->workspace_overlay->update();
}
return v;
+ } else if (name == "tileset_script") {
+ tileset->set_script(p_value);
+ return true;
}
tileset_editor->err_dialog->set_text(TTR("This property can't be changed."));
@@ -2302,6 +2312,9 @@ bool TilesetEditorContext::_get(const StringName &p_name, Variant &r_ret) const
} else if (name == "selected_occlusion") {
r_ret = tileset_editor->edited_occlusion_shape;
v = true;
+ } else if (name == "tileset_script") {
+ r_ret = tileset->get_script();
+ v = true;
}
return v;
}
@@ -2346,6 +2359,9 @@ void TilesetEditorContext::_get_property_list(List<PropertyInfo> *p_list) const
if (tileset_editor->edit_mode == TileSetEditor::EDITMODE_OCCLUSION && tileset_editor->edited_occlusion_shape.is_valid()) {
p_list->push_back(PropertyInfo(Variant::OBJECT, "selected_occlusion", PROPERTY_HINT_RESOURCE_TYPE, tileset_editor->edited_occlusion_shape->get_class()));
}
+ if (!tileset.is_null()) {
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "tileset_script", PROPERTY_HINT_RESOURCE_TYPE, "Script"));
+ }
}
TilesetEditorContext::TilesetEditorContext(TileSetEditor *p_tileset_editor) {
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 39250ab391..3ace179f7d 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -400,8 +400,10 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
editor_data->get_undo_redo().add_do_method(E->get(), "set_script", empty);
editor_data->get_undo_redo().add_undo_method(E->get(), "set_script", existing);
- editor_data->get_undo_redo().add_do_method(E->get(), "set_meta", "_editor_icon", get_icon(E->get()->get_class(), "EditorIcons"));
- editor_data->get_undo_redo().add_undo_method(E->get(), "set_meta", "_editor_icon", E->get()->get_meta("_editor_icon"));
+ if (E->get()->has_meta("_editor_icon")) {
+ editor_data->get_undo_redo().add_do_method(E->get(), "set_meta", "_editor_icon", get_icon(E->get()->get_class(), "EditorIcons"));
+ editor_data->get_undo_redo().add_undo_method(E->get(), "set_meta", "_editor_icon", E->get()->get_meta("_editor_icon"));
+ }
}
}
diff --git a/main/main.cpp b/main/main.cpp
index 21851337b7..a336496d39 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -830,6 +830,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
video_driver = GLOBAL_GET("rendering/quality/driver/driver_name");
}
+ GLOBAL_DEF("rendering/quality/driver/driver_fallback", "Best");
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/driver/driver_fallback", PropertyInfo(Variant::STRING, "rendering/quality/driver/driver_fallback", PROPERTY_HINT_ENUM, "Best,Never"));
+
GLOBAL_DEF("display/window/size/width", 1024);
GLOBAL_DEF("display/window/size/height", 600);
GLOBAL_DEF("display/window/size/resizable", true);
@@ -1040,6 +1043,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
if (err != OK) {
return err;
}
+
if (init_use_custom_pos) {
OS::get_singleton()->set_window_position(init_custom_pos);
}
diff --git a/main/splash_editor.png b/main/splash_editor.png
index f003995d6f..d5bc2f1ce6 100644
--- a/main/splash_editor.png
+++ b/main/splash_editor.png
Binary files differ
diff --git a/methods.py b/methods.py
index e9450d95e2..7aa06f04b8 100644
--- a/methods.py
+++ b/methods.py
@@ -43,7 +43,7 @@ def update_version(module_version_string=""):
f.write("#define VERSION_STATUS \"" + str(version.status) + "\"\n")
f.write("#define VERSION_BUILD \"" + str(build_name) + "\"\n")
f.write("#define VERSION_MODULE_CONFIG \"" + str(version.module_config) + module_version_string + "\"\n")
- f.write("#define VERSION_YEAR " + str(datetime.datetime.now().year) + "\n")
+ f.write("#define VERSION_YEAR " + str(2018) + "\n")
f.close()
# NOTE: It is safe to generate this file here, since this is still executed serially
diff --git a/modules/cvtt/image_compress_cvtt.cpp b/modules/cvtt/image_compress_cvtt.cpp
index 3a371c8597..af92861352 100644
--- a/modules/cvtt/image_compress_cvtt.cpp
+++ b/modules/cvtt/image_compress_cvtt.cpp
@@ -247,8 +247,8 @@ void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::CompressS
}
dst_ofs += (MAX(4, bw) * MAX(4, bh)) >> shift;
- w >>= 1;
- h >>= 1;
+ w = MAX(w / 2, 1);
+ h = MAX(h / 2, 1);
}
if (num_job_threads > 0) {
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index 3b494dbae7..006fbece53 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -1253,6 +1253,25 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
codegen.opcodes.push_back(src_address_b); // argument 2 (unary only takes one parameter)
} break;
+ case GDScriptParser::OperatorNode::OP_IS_BUILTIN: {
+ ERR_FAIL_COND_V(on->arguments.size() != 2, false);
+ ERR_FAIL_COND_V(on->arguments[1]->type != GDScriptParser::Node::TYPE_TYPE, false);
+
+ int slevel = p_stack_level;
+
+ int src_address_a = _parse_expression(codegen, on->arguments[0], slevel);
+ if (src_address_a < 0)
+ return -1;
+
+ if (src_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS)
+ slevel++; //uses stack for return, increase stack
+
+ const GDScriptParser::TypeNode *tn = static_cast<const GDScriptParser::TypeNode *>(on->arguments[1]);
+
+ codegen.opcodes.push_back(GDScriptFunction::OPCODE_IS_BUILTIN); // perform operator
+ codegen.opcodes.push_back(src_address_a); // argument 1
+ codegen.opcodes.push_back((int)tn->vtype); // argument 2 (unary only takes one parameter)
+ } break;
default: {
ERR_EXPLAIN("Bug in bytecode compiler, unexpected operator #" + itos(on->op) + " in parse tree while parsing expression.");
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index bae3f48923..d615b58b24 100644
--- a/modules/gdscript/gdscript_function.cpp
+++ b/modules/gdscript/gdscript_function.cpp
@@ -191,6 +191,7 @@ static String _get_var_type(const Variant *p_type) {
static const void *switch_table_ops[] = { \
&&OPCODE_OPERATOR, \
&&OPCODE_EXTENDS_TEST, \
+ &&OPCODE_IS_BUILTIN, \
&&OPCODE_SET, \
&&OPCODE_GET, \
&&OPCODE_SET_NAMED, \
@@ -536,6 +537,21 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
DISPATCH_OPCODE;
+ OPCODE(OPCODE_IS_BUILTIN) {
+
+ CHECK_SPACE(4);
+
+ GET_VARIANT_PTR(value, 1);
+ Variant::Type var_type = (Variant::Type)_code_ptr[ip + 2];
+ GET_VARIANT_PTR(dst, 3);
+
+ GD_ERR_BREAK(var_type < 0 || var_type >= Variant::VARIANT_MAX);
+
+ *dst = value->get_type() == var_type;
+ ip += 4;
+ }
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_SET) {
CHECK_SPACE(3);
diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h
index 3ce84290fd..633cca35d3 100644
--- a/modules/gdscript/gdscript_function.h
+++ b/modules/gdscript/gdscript_function.h
@@ -136,6 +136,7 @@ public:
enum Opcode {
OPCODE_OPERATOR,
OPCODE_EXTENDS_TEST,
+ OPCODE_IS_BUILTIN,
OPCODE_SET,
OPCODE_GET,
OPCODE_SET_NAMED,
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index a3f5e1819e..7502f09d8a 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -861,6 +861,20 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
op->arguments.push_back(subexpr);
expr=op;*/
+ } else if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_IS && tokenizer->get_token(1) == GDScriptTokenizer::TK_BUILT_IN_TYPE) {
+ // 'is' operator with built-in type
+ OperatorNode *op = alloc_node<OperatorNode>();
+ op->op = OperatorNode::OP_IS_BUILTIN;
+ op->arguments.push_back(expr);
+
+ tokenizer->advance();
+
+ TypeNode *tn = alloc_node<TypeNode>();
+ tn->vtype = tokenizer->get_token_type();
+ op->arguments.push_back(tn);
+ tokenizer->advance();
+
+ expr = op;
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_BRACKET_OPEN) {
// array
tokenizer->advance();
@@ -1071,6 +1085,15 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
expr = op;
+ } else if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_TYPE && expression.size() > 0 && expression[expression.size() - 1].is_op && expression[expression.size() - 1].op == OperatorNode::OP_IS) {
+ Expression e = expression[expression.size() - 1];
+ e.op = OperatorNode::OP_IS_BUILTIN;
+ expression.write[expression.size() - 1] = e;
+
+ TypeNode *tn = alloc_node<TypeNode>();
+ tn->vtype = tokenizer->get_token_type();
+ expr = tn;
+ tokenizer->advance();
} else {
//find list [ or find dictionary {
@@ -1329,6 +1352,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
switch (expression[i].op) {
case OperatorNode::OP_IS:
+ case OperatorNode::OP_IS_BUILTIN:
priority = -1;
break; //before anything
@@ -3915,14 +3939,15 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "FLAGS") {
- //current_export.hint=PROPERTY_HINT_ALL_FLAGS;
tokenizer->advance();
if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
+ ERR_EXPLAIN("Exporting bit flags hint requires string constants.");
+ WARN_DEPRECATED
break;
}
if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
- _set_error("Expected ')' or ',' in bit flags hint.");
+ _set_error("Expected ',' in bit flags hint.");
return;
}
@@ -5793,6 +5818,13 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
case Node::TYPE_CONSTANT: {
node_type = _type_from_variant(static_cast<ConstantNode *>(p_node)->value);
} break;
+ case Node::TYPE_TYPE: {
+ TypeNode *tn = static_cast<TypeNode *>(p_node);
+ node_type.has_type = true;
+ node_type.is_meta_type = true;
+ node_type.kind = DataType::BUILTIN;
+ node_type.builtin_type = tn->vtype;
+ } break;
case Node::TYPE_ARRAY: {
node_type.has_type = true;
node_type.kind = DataType::BUILTIN;
@@ -5896,7 +5928,8 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
// yield can return anything
node_type.has_type = false;
} break;
- case OperatorNode::OP_IS: {
+ case OperatorNode::OP_IS:
+ case OperatorNode::OP_IS_BUILTIN: {
if (op->arguments.size() != 2) {
_set_error("Parser bug: binary operation without 2 arguments.", op->line);
@@ -5913,8 +5946,11 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
}
type_type.is_meta_type = false; // Test the actual type
if (!_is_type_compatible(type_type, value_type) && !_is_type_compatible(value_type, type_type)) {
- // TODO: Make this a warning?
- _set_error("A value of type '" + value_type.to_string() + "' will never be an instance of '" + type_type.to_string() + "'.", op->line);
+ if (op->op == OperatorNode::OP_IS) {
+ _set_error("A value of type '" + value_type.to_string() + "' will never be an instance of '" + type_type.to_string() + "'.", op->line);
+ } else {
+ _set_error("A value of type '" + value_type.to_string() + "' will never be of type '" + type_type.to_string() + "'.", op->line);
+ }
return DataType();
}
}
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index dbe523a0b9..3c51e3f372 100644
--- a/modules/gdscript/gdscript_parser.h
+++ b/modules/gdscript/gdscript_parser.h
@@ -345,6 +345,7 @@ public:
OP_PARENT_CALL,
OP_YIELD,
OP_IS,
+ OP_IS_BUILTIN,
//indexing operator
OP_INDEX,
OP_INDEX_NAMED,
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index 4185f3407d..cc954348f4 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -533,7 +533,6 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_output_dir, bo
cs_icalls_content.push_back("using System;\n"
"using System.Runtime.CompilerServices;\n"
- "using " BINDINGS_NAMESPACE_COLLECTIONS ";\n"
"\n");
cs_icalls_content.push_back("namespace " BINDINGS_NAMESPACE "\n" OPEN_BLOCK);
cs_icalls_content.push_back(INDENT1 "internal static class " BINDINGS_CLASS_NATIVECALLS "\n" INDENT1 OPEN_BLOCK);
@@ -638,7 +637,6 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_output_dir,
cs_icalls_content.push_back("using System;\n"
"using System.Runtime.CompilerServices;\n"
- "using " BINDINGS_NAMESPACE_COLLECTIONS ";\n"
"\n");
cs_icalls_content.push_back("namespace " BINDINGS_NAMESPACE "\n" OPEN_BLOCK);
cs_icalls_content.push_back(INDENT1 "internal static class " BINDINGS_CLASS_NATIVECALLS_EDITOR "\n" INDENT1 OPEN_BLOCK);
@@ -711,10 +709,8 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
List<String> output;
output.push_back("using System;\n"); // IntPtr
-
- if (itype.requires_collections)
- output.push_back("using " BINDINGS_NAMESPACE_COLLECTIONS ";\n"); // Dictionary
-
+ output.push_back("\n#pragma warning disable CS1591 // Disable warning: "
+ "'Missing XML comment for publicly visible type or member'\n");
output.push_back("\nnamespace " BINDINGS_NAMESPACE "\n" OPEN_BLOCK);
const DocData::ClassDoc *class_doc = itype.class_doc;
@@ -737,8 +733,15 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
}
output.push_back(INDENT1 "public ");
- bool is_abstract = itype.is_object_type && !ClassDB::can_instance(itype.name) && ClassDB::is_class_enabled(itype.name); // can_instance returns true if there's a constructor and the class is not 'disabled'
- output.push_back(itype.is_singleton ? "static partial class " : (is_abstract ? "abstract partial class " : "partial class "));
+ if (itype.is_object_type) {
+ if (itype.is_singleton) {
+ output.push_back("static partial class ");
+ } else {
+ output.push_back(itype.is_instantiable ? "partial class " : "abstract partial class ");
+ }
+ } else {
+ output.push_back("partial class ");
+ }
output.push_back(itype.proxy_name);
if (itype.is_singleton) {
@@ -1034,7 +1037,10 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
custom_icalls.push_back(ctor_icall);
}
- output.push_back(INDENT1 CLOSE_BLOCK CLOSE_BLOCK);
+ output.push_back(INDENT1 CLOSE_BLOCK /* class */
+ CLOSE_BLOCK /* namespace */);
+
+ output.push_back("\n#pragma warning restore CS1591\n");
return _save_file(p_output_file, output);
}
@@ -1922,9 +1928,6 @@ void BindingsGenerator::_populate_object_type_interfaces() {
imethod.return_type.cname = Variant::get_type_name(return_info.type);
}
- if (!itype.requires_collections && imethod.return_type.cname == name_cache.type_Dictionary || imethod.return_type.cname == name_cache.type_Array)
- itype.requires_collections = true;
-
for (int i = 0; i < argc; i++) {
PropertyInfo arginfo = method_info.arguments[i];
@@ -1946,9 +1949,6 @@ void BindingsGenerator::_populate_object_type_interfaces() {
iarg.name = escape_csharp_keyword(snake_to_camel_case(iarg.name));
- if (!itype.requires_collections && iarg.type.cname == name_cache.type_Dictionary || imethod.return_type.cname == name_cache.type_Array)
- itype.requires_collections = true;
-
if (m && m->has_default_argument(i)) {
_default_argument_from_variant(m->get_default_argument(i), iarg);
}
@@ -2371,14 +2371,14 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype = TypeInterface();
itype.name = "Array";
itype.cname = itype.name;
- itype.proxy_name = "Collections.Array";
+ itype.proxy_name = itype.name;
itype.c_out = "\treturn memnew(Array(%1));\n";
itype.c_type = itype.name;
itype.c_type_in = itype.c_type + "*";
itype.c_type_out = itype.c_type + "*";
- itype.cs_type = itype.proxy_name;
+ itype.cs_type = BINDINGS_NAMESPACE_COLLECTIONS "." + itype.proxy_name;
itype.cs_in = "%0." CS_SMETHOD_GETINSTANCE "()";
- itype.cs_out = "return new Collections.Array(%0);";
+ itype.cs_out = "return new " + itype.cs_type + "(%0);";
itype.im_type_in = "IntPtr";
itype.im_type_out = "IntPtr";
builtin_types.insert(itype.cname, itype);
@@ -2387,14 +2387,14 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype = TypeInterface();
itype.name = "Dictionary";
itype.cname = itype.name;
- itype.proxy_name = "Collections.Dictionary";
+ itype.proxy_name = itype.name;
itype.c_out = "\treturn memnew(Dictionary(%1));\n";
itype.c_type = itype.name;
itype.c_type_in = itype.c_type + "*";
itype.c_type_out = itype.c_type + "*";
- itype.cs_type = itype.proxy_name;
+ itype.cs_type = BINDINGS_NAMESPACE_COLLECTIONS "." + itype.proxy_name;
itype.cs_in = "%0." CS_SMETHOD_GETINSTANCE "()";
- itype.cs_out = "return new Collections.Dictionary(%0);";
+ itype.cs_out = "return new " + itype.cs_type + "(%0);";
itype.im_type_in = "IntPtr";
itype.im_type_out = "IntPtr";
builtin_types.insert(itype.cname, itype);
@@ -2441,9 +2441,6 @@ void BindingsGenerator::_populate_builtin_type(TypeInterface &r_itype, Variant::
else
iarg.type.cname = Variant::get_type_name(pi.type);
- if (!r_itype.requires_collections && iarg.type.cname == name_cache.type_Dictionary || imethod.return_type.cname == name_cache.type_Array)
- r_itype.requires_collections = true;
-
if ((mi.default_arguments.size() - mi.arguments.size() + i) >= 0)
_default_argument_from_variant(Variant::construct(pi.type, NULL, 0, cerror), iarg);
@@ -2457,9 +2454,6 @@ void BindingsGenerator::_populate_builtin_type(TypeInterface &r_itype, Variant::
imethod.return_type.cname = Variant::get_type_name(mi.return_val.type);
}
- if (!r_itype.requires_collections && imethod.return_type.cname == name_cache.type_Dictionary || imethod.return_type.cname == name_cache.type_Array)
- r_itype.requires_collections = true;
-
if (r_itype.class_doc) {
for (int i = 0; i < r_itype.class_doc->methods.size(); i++) {
if (r_itype.class_doc->methods[i].name == imethod.name) {
diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h
index 5b33a0e53f..735e7ce7cc 100644
--- a/modules/mono/editor/bindings_generator.h
+++ b/modules/mono/editor/bindings_generator.h
@@ -192,7 +192,7 @@ class BindingsGenerator {
/**
* Used only by Object-derived types.
- * Determines if this type is not virtual (incomplete).
+ * Determines if this type is not abstract (incomplete).
* e.g.: CanvasItem cannot be instantiated.
*/
bool is_instantiable;
@@ -204,12 +204,6 @@ class BindingsGenerator {
*/
bool memory_own;
- /**
- * Determines if the file must have a using directive for System.Collections.Generic
- * e.g.: When the generated class makes use of Dictionary
- */
- bool requires_collections;
-
// !! The comments of the following fields make reference to other fields via square brackets, e.g.: [field_name]
// !! When renaming those fields, make sure to rename their references in the comments
@@ -295,7 +289,7 @@ class BindingsGenerator {
/**
* Type used for method signatures, both for parameters and the return type.
- * Same as [proxy_name] except for variable arguments (VarArg).
+ * Same as [proxy_name] except for variable arguments (VarArg) and collections (which include the namespace).
*/
String cs_type;
@@ -414,7 +408,6 @@ class BindingsGenerator {
is_instantiable = false;
memory_own = false;
- requires_collections = false;
c_arg_in = "%s";
diff --git a/modules/mono/glue/cs_files/Basis.cs b/modules/mono/glue/cs_files/Basis.cs
index c280d32c61..10286f3832 100644
--- a/modules/mono/glue/cs_files/Basis.cs
+++ b/modules/mono/glue/cs_files/Basis.cs
@@ -426,7 +426,7 @@ namespace Godot
public Basis(Quat quat)
{
- real_t s = 2.0f / quat.LengthSquared();
+ real_t s = 2.0f / quat.LengthSquared;
real_t xs = quat.x * s;
real_t ys = quat.y * s;
diff --git a/modules/mono/glue/cs_files/Quat.cs b/modules/mono/glue/cs_files/Quat.cs
index c69c55d997..eaa027eb69 100644
--- a/modules/mono/glue/cs_files/Quat.cs
+++ b/modules/mono/glue/cs_files/Quat.cs
@@ -11,18 +11,11 @@ namespace Godot
[StructLayout(LayoutKind.Sequential)]
public struct Quat : IEquatable<Quat>
{
- private static readonly Quat identity = new Quat(0f, 0f, 0f, 1f);
-
public real_t x;
public real_t y;
public real_t z;
public real_t w;
- public static Quat Identity
- {
- get { return identity; }
- }
-
public real_t this[int index]
{
get
@@ -63,6 +56,16 @@ namespace Godot
}
}
+ public real_t Length
+ {
+ get { return Mathf.Sqrt(LengthSquared); }
+ }
+
+ public real_t LengthSquared
+ {
+ get { return Dot(this); }
+ }
+
public Quat CubicSlerp(Quat b, Quat preA, Quat postB, real_t t)
{
real_t t2 = (1.0f - t) * t * 2f;
@@ -76,24 +79,20 @@ namespace Godot
return x * b.x + y * b.y + z * b.z + w * b.w;
}
- public Quat Inverse()
- {
- return new Quat(-x, -y, -z, w);
- }
-
- public real_t Length()
+ public Vector3 GetEuler()
{
- return Mathf.Sqrt(LengthSquared());
+ var basis = new Basis(this);
+ return basis.GetEuler();
}
- public real_t LengthSquared()
+ public Quat Inverse()
{
- return Dot(this);
+ return new Quat(-x, -y, -z, w);
}
public Quat Normalized()
{
- return this / Length();
+ return this / Length;
}
public void Set(real_t x, real_t y, real_t z, real_t w)
@@ -103,12 +102,20 @@ namespace Godot
this.z = z;
this.w = w;
}
+
public void Set(Quat q)
{
- x = q.x;
- y = q.y;
- z = q.z;
- w = q.w;
+ this = q;
+ }
+
+ public void SetAxisAngle(Vector3 axis, real_t angle)
+ {
+ this = new Quat(axis, angle);
+ }
+
+ public void SetEuler(Vector3 eulerYXZ)
+ {
+ this = new Quat(eulerYXZ);
}
public Quat Slerp(Quat b, real_t t)
@@ -192,6 +199,9 @@ namespace Godot
return new Vector3(q.x, q.y, q.z);
}
+ // Static Readonly Properties
+ public static Quat Identity { get; } = new Quat(0f, 0f, 0f, 1f);
+
// Constructors
public Quat(real_t x, real_t y, real_t z, real_t w)
{
@@ -199,15 +209,46 @@ namespace Godot
this.y = y;
this.z = z;
this.w = w;
- }
+ }
+
+ public bool IsNormalized()
+ {
+ return Mathf.Abs(LengthSquared - 1) <= Mathf.Epsilon;
+ }
+
public Quat(Quat q)
- {
- x = q.x;
- y = q.y;
- z = q.z;
- w = q.w;
+ {
+ this = q;
+ }
+
+ public Quat(Basis basis)
+ {
+ this = basis.Quat();
}
-
+
+ public Quat(Vector3 eulerYXZ)
+ {
+ real_t half_a1 = eulerYXZ.y * (real_t)0.5;
+ real_t half_a2 = eulerYXZ.x * (real_t)0.5;
+ real_t half_a3 = eulerYXZ.z * (real_t)0.5;
+
+ // R = Y(a1).X(a2).Z(a3) convention for Euler angles.
+ // Conversion to quaternion as listed in https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770024290.pdf (page A-6)
+ // a3 is the angle of the first rotation, following the notation in this reference.
+
+ real_t cos_a1 = Mathf.Cos(half_a1);
+ real_t sin_a1 = Mathf.Sin(half_a1);
+ real_t cos_a2 = Mathf.Cos(half_a2);
+ real_t sin_a2 = Mathf.Sin(half_a2);
+ real_t cos_a3 = Mathf.Cos(half_a3);
+ real_t sin_a3 = Mathf.Sin(half_a3);
+
+ x = sin_a1 * cos_a2 * sin_a3 + cos_a1 * sin_a2 * cos_a3;
+ y = sin_a1 * cos_a2 * cos_a3 - cos_a1 * sin_a2 * sin_a3;
+ z = -sin_a1 * sin_a2 * cos_a3 + cos_a1 * cos_a2 * sin_a3;
+ w = sin_a1 * sin_a2 * sin_a3 + cos_a1 * cos_a2 * cos_a3;
+ }
+
public Quat(Vector3 axis, real_t angle)
{
real_t d = axis.Length();
diff --git a/modules/squish/image_compress_squish.cpp b/modules/squish/image_compress_squish.cpp
index 653dd82351..bb8a4bdbea 100644
--- a/modules/squish/image_compress_squish.cpp
+++ b/modules/squish/image_compress_squish.cpp
@@ -193,8 +193,8 @@ void image_compress_squish(Image *p_image, float p_lossy_quality, Image::Compres
int src_ofs = p_image->get_mipmap_offset(i);
squish::CompressImage(&rb[src_ofs], w, h, &wb[dst_ofs], squish_comp);
dst_ofs += (MAX(4, bw) * MAX(4, bh)) >> shift;
- w >>= 1;
- h >>= 1;
+ w = MAX(w / 2, 1);
+ h = MAX(h / 2, 1);
}
rb = PoolVector<uint8_t>::Read();
diff --git a/modules/webm/libvpx/SCsub b/modules/webm/libvpx/SCsub
index c681e2b34f..2daf8c282f 100644
--- a/modules/webm/libvpx/SCsub
+++ b/modules/webm/libvpx/SCsub
@@ -38,7 +38,6 @@ libvpx_sources = [
"vp8/decoder/decodemv.c",
"vp8/decoder/detokenize.c",
"vp8/decoder/onyxd_if.c",
- "vp8/decoder/threading.c",
"vp9/vp9_dx_iface.c",
@@ -102,6 +101,10 @@ libvpx_sources = [
"vpx_util/vpx_thread.c"
]
+libvpx_sources_mt = [
+ "vp8/decoder/threading.c",
+]
+
libvpx_sources_intrin_x86 = [
"vp8/common/x86/filter_x86.c",
"vp8/common/x86/loopfilter_x86.c",
@@ -231,6 +234,7 @@ libvpx_sources_arm_neon_gas_apple = [
]
libvpx_sources = [libvpx_dir + file for file in libvpx_sources]
+libvpx_sources_mt = [libvpx_dir + file for file in libvpx_sources_mt]
libvpx_sources_intrin_x86 = [libvpx_dir + file for file in libvpx_sources_intrin_x86]
libvpx_sources_intrin_x86_mmx = [libvpx_dir + file for file in libvpx_sources_intrin_x86_mmx]
libvpx_sources_intrin_x86_sse2 = [libvpx_dir + file for file in libvpx_sources_intrin_x86_sse2]
@@ -253,6 +257,8 @@ env_webm.Append(CPPPATH=[libvpx_dir])
env_libvpx = env.Clone()
env_libvpx.Append(CPPPATH=[libvpx_dir])
+webm_multithread = env["platform"] != 'javascript'
+
cpu_bits = env["bits"]
webm_cpu_x86 = False
webm_cpu_arm = False
@@ -338,6 +344,10 @@ if webm_simd_optimizations == False:
print("WebM SIMD optimizations are disabled. Check if your CPU architecture, CPU bits or platform are supported!")
env_libvpx.add_source_files(env.modules_sources, libvpx_sources)
+
+if webm_multithread:
+ env_libvpx.add_source_files(env.modules_sources, libvpx_sources_mt)
+
if webm_cpu_x86:
is_clang_or_gcc = ('gcc' in env["CC"]) or ('clang' in env["CC"]) or ("OSXCROSS_ROOT" in os.environ)
diff --git a/platform/android/detect.py b/platform/android/detect.py
index b22e85b2c1..953a2fa6d2 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -258,9 +258,10 @@ def configure(env):
if ndk_version != None and LooseVersion(ndk_version) >= LooseVersion("15.0.4075724"):
if LooseVersion(ndk_version) >= LooseVersion("17.1.4828580"):
env.Append(LINKFLAGS=['-Wl,--exclude-libs,libgcc.a','-Wl,--exclude-libs,libatomic.a','-nostdlib++'])
+ else:
+ env.Append(LINKFLAGS=[env["ANDROID_NDK_ROOT"] +"/sources/cxx-stl/llvm-libc++/libs/"+arch_subpath+"/libandroid_support.a"])
env.Append(LINKFLAGS=['-shared', '--sysroot=' + lib_sysroot, '-Wl,--warn-shared-textrel'])
env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++/libs/"+arch_subpath+"/"])
- env.Append(LINKFLAGS=[env["ANDROID_NDK_ROOT"] +"/sources/cxx-stl/llvm-libc++/libs/"+arch_subpath+"/libandroid_support.a"])
env.Append(LINKFLAGS=[env["ANDROID_NDK_ROOT"] +"/sources/cxx-stl/llvm-libc++/libs/"+arch_subpath+"/libc++_shared.so"])
else:
env.Append(LINKFLAGS=['-shared', '--sysroot=' + lib_sysroot, '-Wl,--warn-shared-textrel'])
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index c8bdf98923..74c40bde72 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -62,12 +62,19 @@ public:
int OS_Android::get_video_driver_count() const {
- return 1;
+ return 2;
}
const char *OS_Android::get_video_driver_name(int p_driver) const {
- return "GLES2";
+ switch (p_driver) {
+ case VIDEO_DRIVER_GLES3:
+ return "GLES3";
+ case VIDEO_DRIVER_GLES2:
+ return "GLES2";
+ }
+ ERR_EXPLAIN("Invalid video driver index " + itos(p_driver));
+ ERR_FAIL_V(NULL);
}
int OS_Android::get_audio_driver_count() const {
@@ -132,26 +139,55 @@ Error OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int
bool use_gl3 = get_gl_version_code_func() >= 0x00030000;
use_gl3 = use_gl3 && (GLOBAL_GET("rendering/quality/driver/driver_name") == "GLES3");
- use_gl2 = !use_gl3;
-
- if (gfx_init_func)
- gfx_init_func(gfx_init_ud, use_gl2);
+ bool gl_initialization_error = false;
+
+ while (true) {
+ if (use_gl3) {
+ if (RasterizerGLES3::is_viable() == OK) {
+ if (gfx_init_func)
+ gfx_init_func(gfx_init_ud, false);
+ RasterizerGLES3::register_config();
+ RasterizerGLES3::make_current();
+ break;
+ } else {
+ if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best") {
+ p_video_driver = VIDEO_DRIVER_GLES2;
+ use_gl3 = false;
+ continue;
+ } else {
+ gl_initialization_error = true;
+ break;
+ }
+ }
+ } else {
+ if (RasterizerGLES2::is_viable() == OK) {
+ if (gfx_init_func)
+ gfx_init_func(gfx_init_ud, true);
+ RasterizerGLES2::register_config();
+ RasterizerGLES2::make_current();
+ break;
+ } else {
+ gl_initialization_error = true;
+ break;
+ }
+ }
+ }
- if (use_gl2) {
- RasterizerGLES2::register_config();
- RasterizerGLES2::make_current();
- video_driver_index = VIDEO_DRIVER_GLES2;
- } else {
- RasterizerGLES3::register_config();
- RasterizerGLES3::make_current();
- video_driver_index = VIDEO_DRIVER_GLES3;
+ if (gl_initialization_error) {
+ OS::get_singleton()->alert("Your device does not support any of the supported OpenGL versions.\n"
+ "Please try updating your Android version.",
+ "Unable to initialize Video driver");
+ return ERR_UNAVAILABLE;
}
+ video_driver_index = p_video_driver;
+
visual_server = memnew(VisualServerRaster);
/* if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
visual_server = memnew(VisualServerWrapMT(visual_server, false));
};*/
+
visual_server->init();
// visual_server->cursor_set_visible(false, 0);
diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp
index a4538a6673..addef61ec7 100644
--- a/platform/iphone/os_iphone.cpp
+++ b/platform/iphone/os_iphone.cpp
@@ -99,8 +99,11 @@ int OSIPhone::get_current_video_driver() const {
Error OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
- video_driver_index = p_video_driver; //this may be misleading
+ video_driver_index = VIDEO_DRIVER_GLES3;
+ if (RasterizerGLES3::is_viable() != OK) {
+ return ERR_UNAVAILABLE;
+ }
RasterizerGLES3::register_config();
RasterizerGLES3::make_current();
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index fc909f6619..17b31f8d73 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -25,7 +25,6 @@ def get_opts():
def get_flags():
return [
('tools', False),
- ('module_theora_enabled', False),
# Disabling the mbedtls module reduces file size.
# The module has little use due to the limited networking functionality
# in this platform. For the available networking methods, the browser
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index 5a8a05d4df..80699b0d32 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -652,23 +652,57 @@ Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver,
attributes.alpha = false;
attributes.antialias = false;
ERR_FAIL_INDEX_V(p_video_driver, VIDEO_DRIVER_MAX, ERR_INVALID_PARAMETER);
- switch (p_video_driver) {
- case VIDEO_DRIVER_GLES3:
- attributes.majorVersion = 2;
- RasterizerGLES3::register_config();
- RasterizerGLES3::make_current();
- break;
- case VIDEO_DRIVER_GLES2:
- attributes.majorVersion = 1;
- RasterizerGLES2::register_config();
- RasterizerGLES2::make_current();
- break;
+
+ bool gles3 = true;
+ if (p_video_driver == VIDEO_DRIVER_GLES2) {
+ gles3 = false;
+ }
+
+ bool gl_initialization_error = false;
+
+ while (true) {
+ if (gles3) {
+ if (RasterizerGLES3::is_viable() == OK) {
+ attributes.majorVersion = 2;
+ RasterizerGLES3::register_config();
+ RasterizerGLES3::make_current();
+ break;
+ } else {
+ if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best") {
+ p_video_driver = VIDEO_DRIVER_GLES2;
+ gles3 = false;
+ continue;
+ } else {
+ gl_initialization_error = true;
+ break;
+ }
+ }
+ } else {
+ if (RasterizerGLES2::is_viable() == OK) {
+ attributes.majorVersion = 1;
+ RasterizerGLES2::register_config();
+ RasterizerGLES2::make_current();
+ break;
+ } else {
+ gl_initialization_error = true;
+ break;
+ }
+ }
}
- video_driver_index = p_video_driver;
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context(NULL, &attributes);
- ERR_EXPLAIN("WebGL " + itos(attributes.majorVersion) + ".0 not available");
- ERR_FAIL_COND_V(emscripten_webgl_make_context_current(ctx) != EMSCRIPTEN_RESULT_SUCCESS, ERR_UNAVAILABLE);
+ if (emscripten_webgl_make_context_current(ctx) != EMSCRIPTEN_RESULT_SUCCESS) {
+ gl_initialization_error = true;
+ }
+
+ if (gl_initialization_error) {
+ OS::get_singleton()->alert("Your browser does not support any of the supported WebGL versions.\n"
+ "Please update your browser version.",
+ "Unable to initialize Video driver");
+ return ERR_UNAVAILABLE;
+ }
+
+ video_driver_index = p_video_driver;
video_mode = p_desired;
// Can't fulfil fullscreen request during start-up due to browser security.
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index 41cfada723..79d7ec410a 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -1276,8 +1276,6 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
}
- video_driver_index = p_video_driver;
-
ADD_ATTR2(NSOpenGLPFAColorSize, colorBits);
/*
@@ -1333,22 +1331,58 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
/*** END OSX INITIALIZATION ***/
- // only opengl support here...
+ bool gles3 = true;
if (p_video_driver == VIDEO_DRIVER_GLES2) {
- RasterizerGLES2::register_config();
- RasterizerGLES2::make_current();
- } else {
- RasterizerGLES3::register_config();
- RasterizerGLES3::make_current();
+ gles3 = false;
}
+ bool editor = Engine::get_singleton()->is_editor_hint();
+ bool gl_initialization_error = false;
+
+ while (true) {
+ if (gles3) {
+ if (RasterizerGLES3::is_viable() == OK) {
+ RasterizerGLES3::register_config();
+ RasterizerGLES3::make_current();
+ break;
+ } else {
+ if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best" || editor) {
+ p_video_driver = VIDEO_DRIVER_GLES2;
+ gles3 = false;
+ continue;
+ } else {
+ gl_initialization_error = true;
+ break;
+ }
+ }
+ } else {
+ if (RasterizerGLES2::is_viable() == OK) {
+ RasterizerGLES2::register_config();
+ RasterizerGLES2::make_current();
+ break;
+ } else {
+ gl_initialization_error = true;
+ break;
+ }
+ }
+ }
+
+ if (gl_initialization_error) {
+ OS::get_singleton()->alert("Your video card driver does not support any of the supported OpenGL versions.\n"
+ "Please update your drivers or if you have a very old or integrated GPU upgrade it.",
+ "Unable to initialize Video driver");
+ return ERR_UNAVAILABLE;
+ }
+
+ video_driver_index = p_video_driver;
+
visual_server = memnew(VisualServerRaster);
if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
}
- visual_server->init();
+ visual_server->init();
AudioDriverManager::initialize(p_audio_driver);
input = memnew(InputDefault);
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index 8549a44ce5..b2eb3450e2 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -187,12 +187,78 @@ Error OSUWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
main_loop = NULL;
outside = true;
+ ContextEGL::Driver opengl_api_type = ContextEGL::GLES_2_0;
+
if (p_video_driver == VIDEO_DRIVER_GLES2) {
- gl_context = memnew(ContextEGL(window, ContextEGL::GLES_2_0));
- } else {
- gl_context = memnew(ContextEGL(window, ContextEGL::GLES_3_0));
+ opengl_api_type = ContextEGL::GLES_2_0;
+ }
+
+ bool gl_initialization_error = false;
+
+ gl_context = NULL;
+ while (!gl_context) {
+ gl_context = memnew(ContextEGL(window, opengl_api_type));
+
+ if (gl_context->initialize() != OK) {
+ memdelete(gl_context);
+ gl_context = NULL;
+
+ if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best") {
+ if (p_video_driver == VIDEO_DRIVER_GLES2) {
+ gl_initialization_error = true;
+ break;
+ }
+
+ p_video_driver = VIDEO_DRIVER_GLES2;
+ opengl_api_type = ContextEGL::GLES_2_0;
+ } else {
+ gl_initialization_error = true;
+ break;
+ }
+ }
+ }
+
+ while (true) {
+ if (opengl_api_type == ContextEGL::GLES_3_0) {
+ if (RasterizerGLES3::is_viable() == OK) {
+ RasterizerGLES3::register_config();
+ RasterizerGLES3::make_current();
+ break;
+ } else {
+ if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best") {
+ p_video_driver = VIDEO_DRIVER_GLES2;
+ opengl_api_type = ContextEGL::GLES_2_0;
+ continue;
+ } else {
+ gl_initialization_error = true;
+ break;
+ }
+ }
+ }
+
+ if (opengl_api_type == ContextEGL::GLES_2_0) {
+ if (RasterizerGLES2::is_viable() == OK) {
+ RasterizerGLES2::register_config();
+ RasterizerGLES2::make_current();
+ break;
+ } else {
+ gl_initialization_error = true;
+ break;
+ }
+ }
+ }
+
+ if (gl_initialization_error) {
+ OS::get_singleton()->alert("Your video card driver does not support any of the supported OpenGL versions.\n"
+ "Please update your drivers or if you have a very old or integrated GPU upgrade it.",
+ "Unable to initialize Video driver");
+ return ERR_UNAVAILABLE;
}
- gl_context->initialize();
+
+ video_driver_index = p_video_driver;
+ gl_context->make_current();
+ gl_context->set_use_vsync(video_mode.use_vsync);
+
VideoMode vm;
vm.width = gl_context->get_window_width();
vm.height = gl_context->get_window_height();
@@ -230,19 +296,6 @@ Error OSUWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
set_video_mode(vm);
- gl_context->make_current();
-
- if (p_video_driver == VIDEO_DRIVER_GLES2) {
- RasterizerGLES2::register_config();
- RasterizerGLES2::make_current();
- } else {
- RasterizerGLES3::register_config();
- RasterizerGLES3::make_current();
- }
- gl_context->set_use_vsync(vm.use_vsync);
-
- video_driver_index = p_video_driver;
-
visual_server = memnew(VisualServerRaster);
// FIXME: Reimplement threaded rendering? Or remove?
/*
@@ -253,7 +306,6 @@ Error OSUWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
*/
visual_server->init();
-
input = memnew(InputDefault);
joypad = ref new JoypadUWP(input);
diff --git a/platform/windows/context_gl_win.cpp b/platform/windows/context_gl_win.cpp
index 59435b04ea..794f6df31f 100644
--- a/platform/windows/context_gl_win.cpp
+++ b/platform/windows/context_gl_win.cpp
@@ -108,28 +108,24 @@ Error ContextGL_Win::initialize() {
hDC = GetDC(hWnd);
if (!hDC) {
- MessageBox(NULL, "Can't Create A GL Device Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
return ERR_CANT_CREATE; // Return FALSE
}
pixel_format = ChoosePixelFormat(hDC, &pfd);
if (!pixel_format) // Did Windows Find A Matching Pixel Format?
{
- MessageBox(NULL, "Can't Find A Suitable pixel_format.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
return ERR_CANT_CREATE; // Return FALSE
}
BOOL ret = SetPixelFormat(hDC, pixel_format, &pfd);
if (!ret) // Are We Able To Set The Pixel Format?
{
- MessageBox(NULL, "Can't Set The pixel_format.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
return ERR_CANT_CREATE; // Return FALSE
}
hRC = wglCreateContext(hDC);
if (!hRC) // Are We Able To Get A Rendering Context?
{
- MessageBox(NULL, "Can't Create A Temporary GL Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
return ERR_CANT_CREATE; // Return FALSE
}
@@ -151,7 +147,6 @@ Error ContextGL_Win::initialize() {
if (wglCreateContextAttribsARB == NULL) //OpenGL 3.0 is not supported
{
- MessageBox(NULL, "Cannot get Proc Address for CreateContextAttribs", "ERROR", MB_OK | MB_ICONEXCLAMATION);
wglDeleteContext(hRC);
return ERR_CANT_CREATE;
}
@@ -159,7 +154,6 @@ Error ContextGL_Win::initialize() {
HGLRC new_hRC = wglCreateContextAttribsARB(hDC, 0, attribs);
if (!new_hRC) {
wglDeleteContext(hRC);
- MessageBox(NULL, "Can't Create An OpenGL 3.3 Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
return ERR_CANT_CREATE; // Return false
}
wglMakeCurrent(hDC, NULL);
@@ -168,7 +162,6 @@ Error ContextGL_Win::initialize() {
if (!wglMakeCurrent(hDC, hRC)) // Try To Activate The Rendering Context
{
- MessageBox(NULL, "Can't Activate The GL 3.3 Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
return ERR_CANT_CREATE; // Return FALSE
}
}
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index fa8717a4b8..7009df8e57 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -190,28 +190,6 @@ BOOL WINAPI HandlerRoutine(_In_ DWORD dwCtrlType) {
}
}
-BOOL CALLBACK _CloseWindowsEnum(HWND hWnd, LPARAM lParam) {
- DWORD dwID;
-
- GetWindowThreadProcessId(hWnd, &dwID);
-
- if (dwID == (DWORD)lParam) {
- PostMessage(hWnd, WM_CLOSE, 0, 0);
- }
-
- return TRUE;
-}
-
-bool _close_gracefully(const PROCESS_INFORMATION &pi, const DWORD dwStopWaitMsec) {
- if (!EnumWindows(_CloseWindowsEnum, pi.dwProcessId))
- return false;
-
- if (WaitForSingleObject(pi.hProcess, dwStopWaitMsec) != WAIT_OBJECT_0)
- return false;
-
- return true;
-}
-
void OS_Windows::initialize_debugging() {
SetConsoleCtrlHandler(HandlerRoutine, TRUE);
@@ -1273,21 +1251,74 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
}
#if defined(OPENGL_ENABLED)
+
+ bool gles3_context = true;
if (p_video_driver == VIDEO_DRIVER_GLES2) {
- gl_context = memnew(ContextGL_Win(hWnd, false));
- gl_context->initialize();
+ gles3_context = false;
+ }
- RasterizerGLES2::register_config();
- RasterizerGLES2::make_current();
- } else {
- gl_context = memnew(ContextGL_Win(hWnd, true));
- gl_context->initialize();
+ bool editor = Engine::get_singleton()->is_editor_hint();
+ bool gl_initialization_error = false;
+
+ gl_context = NULL;
+ while (!gl_context) {
+ gl_context = memnew(ContextGL_Win(hWnd, gles3_context));
+
+ if (gl_context->initialize() != OK) {
+ memdelete(gl_context);
+ gl_context = NULL;
+
+ if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best" || editor) {
+ if (p_video_driver == VIDEO_DRIVER_GLES2) {
+ gl_initialization_error = true;
+ break;
+ }
- RasterizerGLES3::register_config();
- RasterizerGLES3::make_current();
+ p_video_driver = VIDEO_DRIVER_GLES2;
+ gles3_context = false;
+ } else {
+ gl_initialization_error = true;
+ break;
+ }
+ }
}
- video_driver_index = p_video_driver; // FIXME TODO - FIX IF DRIVER DETECTION HAPPENS AND GLES2 MUST BE USED
+ while (true) {
+ if (gles3_context) {
+ if (RasterizerGLES3::is_viable() == OK) {
+ RasterizerGLES3::register_config();
+ RasterizerGLES3::make_current();
+ break;
+ } else {
+ if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best" || editor) {
+ p_video_driver = VIDEO_DRIVER_GLES2;
+ gles3_context = false;
+ continue;
+ } else {
+ gl_initialization_error = true;
+ break;
+ }
+ }
+ } else {
+ if (RasterizerGLES2::is_viable() == OK) {
+ RasterizerGLES2::register_config();
+ RasterizerGLES2::make_current();
+ break;
+ } else {
+ gl_initialization_error = true;
+ break;
+ }
+ }
+ }
+
+ if (gl_initialization_error) {
+ OS::get_singleton()->alert("Your video card driver does not support any of the supported OpenGL versions.\n"
+ "Please update your drivers or if you have a very old or integrated GPU upgrade it.",
+ "Unable to initialize Video driver");
+ return ERR_UNAVAILABLE;
+ }
+
+ video_driver_index = p_video_driver;
gl_context->set_use_vsync(video_mode.use_vsync);
#endif
@@ -2411,26 +2442,20 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
return OK;
};
-Error OS_Windows::kill(const ProcessID &p_pid, const int p_max_wait_msec) {
+Error OS_Windows::kill(const ProcessID &p_pid) {
+
ERR_FAIL_COND_V(!process_map->has(p_pid), FAILED);
const PROCESS_INFORMATION pi = (*process_map)[p_pid].pi;
process_map->erase(p_pid);
- Error result;
-
- if (p_max_wait_msec != -1 && _close_gracefully(pi, p_max_wait_msec)) {
- result = OK;
- } else {
- const int ret = TerminateProcess(pi.hProcess, 0);
- result = ret != 0 ? OK : FAILED;
- }
+ const int ret = TerminateProcess(pi.hProcess, 0);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
- return result;
-}
+ return ret != 0 ? OK : FAILED;
+};
int OS_Windows::get_process_id() const {
return _getpid();
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index 243d4bb328..c9fa46052a 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -259,7 +259,7 @@ public:
virtual uint64_t get_ticks_usec() const;
virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false);
- virtual Error kill(const ProcessID &p_pid, const int p_stop_max_wait_msec = -1);
+ virtual Error kill(const ProcessID &p_pid);
virtual int get_process_id() const;
virtual bool has_environment(const String &p_var) const;
diff --git a/platform/x11/context_gl_x11.cpp b/platform/x11/context_gl_x11.cpp
index 5a239e326b..8c1869a1f1 100644
--- a/platform/x11/context_gl_x11.cpp
+++ b/platform/x11/context_gl_x11.cpp
@@ -116,9 +116,14 @@ Error ContextGL_X11::initialize() {
};
int fbcount;
- GLXFBConfig fbconfig;
+ GLXFBConfig fbconfig = 0;
XVisualInfo *vi = NULL;
+ XSetWindowAttributes swa;
+ swa.event_mask = StructureNotifyMask;
+ swa.border_pixel = 0;
+ unsigned long valuemask = CWBorderPixel | CWColormap | CWEventMask;
+
if (OS::get_singleton()->is_layered_allowed()) {
GLXFBConfig *fbc = glXChooseFBConfig(x11_display, DefaultScreen(x11_display), visual_attribs_layered, &fbcount);
ERR_FAIL_COND_V(!fbc, ERR_UNCONFIGURED);
@@ -142,16 +147,10 @@ Error ContextGL_X11::initialize() {
}
ERR_FAIL_COND_V(!fbconfig, ERR_UNCONFIGURED);
- XSetWindowAttributes swa;
-
- swa.colormap = XCreateColormap(x11_display, RootWindow(x11_display, vi->screen), vi->visual, AllocNone);
- swa.border_pixel = 0;
swa.background_pixmap = None;
swa.background_pixel = 0;
swa.border_pixmap = None;
- swa.event_mask = StructureNotifyMask;
-
- x11_window = XCreateWindow(x11_display, RootWindow(x11_display, vi->screen), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask | CWBackPixel, &swa);
+ valuemask |= CWBackPixel;
} else {
GLXFBConfig *fbc = glXChooseFBConfig(x11_display, DefaultScreen(x11_display), visual_attribs, &fbcount);
@@ -160,42 +159,21 @@ Error ContextGL_X11::initialize() {
vi = glXGetVisualFromFBConfig(x11_display, fbc[0]);
fbconfig = fbc[0];
-
- XSetWindowAttributes swa;
-
- swa.colormap = XCreateColormap(x11_display, RootWindow(x11_display, vi->screen), vi->visual, AllocNone);
- swa.border_pixel = 0;
- swa.event_mask = StructureNotifyMask;
-
- x11_window = XCreateWindow(x11_display, RootWindow(x11_display, vi->screen), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &swa);
}
- ERR_FAIL_COND_V(!x11_window, ERR_UNCONFIGURED);
- set_class_hint(x11_display, x11_window);
- XMapWindow(x11_display, x11_window);
-
- int (*oldHandler)(Display *, XErrorEvent *) =
- XSetErrorHandler(&ctxErrorHandler);
+ int (*oldHandler)(Display *, XErrorEvent *) = XSetErrorHandler(&ctxErrorHandler);
switch (context_type) {
- case GLES_2_0_COMPATIBLE:
case OLDSTYLE: {
+
p->glx_context = glXCreateContext(x11_display, vi, 0, GL_TRUE);
+ ERR_FAIL_COND_V(!p->glx_context, ERR_UNCONFIGURED);
} break;
- /*
- case ContextType::GLES_2_0_COMPATIBLE: {
-
- static int context_attribs[] = {
- GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
- GLX_CONTEXT_MINOR_VERSION_ARB, 0,
- None
- };
+ case GLES_2_0_COMPATIBLE: {
- p->glx_context = glXCreateContextAttribsARB(x11_display, fbconfig, NULL, true, context_attribs);
- ERR_EXPLAIN("Could not obtain an OpenGL 3.0 context!");
+ p->glx_context = glXCreateNewContext(x11_display, fbconfig, GLX_RGBA_TYPE, 0, true);
ERR_FAIL_COND_V(!p->glx_context, ERR_UNCONFIGURED);
} break;
- */
case GLES_3_0_COMPATIBLE: {
static int context_attribs[] = {
@@ -207,24 +185,22 @@ Error ContextGL_X11::initialize() {
};
p->glx_context = glXCreateContextAttribsARB(x11_display, fbconfig, NULL, true, context_attribs);
- ERR_EXPLAIN("Could not obtain an OpenGL 3.3 context!");
ERR_FAIL_COND_V(ctxErrorOccurred || !p->glx_context, ERR_UNCONFIGURED);
} break;
}
+ swa.colormap = XCreateColormap(x11_display, RootWindow(x11_display, vi->screen), vi->visual, AllocNone);
+ x11_window = XCreateWindow(x11_display, RootWindow(x11_display, vi->screen), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height, 0, vi->depth, InputOutput, vi->visual, valuemask, &swa);
+
+ ERR_FAIL_COND_V(!x11_window, ERR_UNCONFIGURED);
+ set_class_hint(x11_display, x11_window);
+ XMapWindow(x11_display, x11_window);
+
XSync(x11_display, False);
XSetErrorHandler(oldHandler);
glXMakeCurrent(x11_display, x11_window, p->glx_context);
- /*
- glWrapperInit(wrapper_get_proc_address);
- glFlush();
-
- glXSwapBuffers(x11_display,x11_window);
-*/
- //glXMakeCurrent(x11_display, None, NULL);
-
XFree(vi);
return OK;
@@ -297,7 +273,6 @@ ContextGL_X11::ContextGL_X11(::Display *p_x11_display, ::Window &p_x11_window, c
ContextGL_X11::~ContextGL_X11() {
release_current();
glXDestroyContext(x11_display, p->glx_context);
-
memdelete(p);
}
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index e4a72e0715..a62bd714d2 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -274,21 +274,70 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
opengl_api_type = ContextGL_X11::GLES_2_0_COMPATIBLE;
}
- context_gl = memnew(ContextGL_X11(x11_display, x11_window, current_videomode, opengl_api_type));
- context_gl->initialize();
+ bool editor = Engine::get_singleton()->is_editor_hint();
+ bool gl_initialization_error = false;
- switch (opengl_api_type) {
- case ContextGL_X11::GLES_2_0_COMPATIBLE: {
- RasterizerGLES2::register_config();
- RasterizerGLES2::make_current();
- } break;
- case ContextGL_X11::GLES_3_0_COMPATIBLE: {
- RasterizerGLES3::register_config();
- RasterizerGLES3::make_current();
- } break;
+ context_gl = NULL;
+ while (!context_gl) {
+ context_gl = memnew(ContextGL_X11(x11_display, x11_window, current_videomode, opengl_api_type));
+
+ if (context_gl->initialize() != OK) {
+ memdelete(context_gl);
+ context_gl = NULL;
+
+ if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best" || editor) {
+ if (p_video_driver == VIDEO_DRIVER_GLES2) {
+ gl_initialization_error = true;
+ break;
+ }
+
+ p_video_driver = VIDEO_DRIVER_GLES2;
+ opengl_api_type = ContextGL_X11::GLES_2_0_COMPATIBLE;
+ } else {
+ gl_initialization_error = true;
+ break;
+ }
+ }
+ }
+
+ while (true) {
+ if (opengl_api_type == ContextGL_X11::GLES_3_0_COMPATIBLE) {
+ if (RasterizerGLES3::is_viable() == OK) {
+ RasterizerGLES3::register_config();
+ RasterizerGLES3::make_current();
+ break;
+ } else {
+ if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best" || editor) {
+ p_video_driver = VIDEO_DRIVER_GLES2;
+ opengl_api_type = ContextGL_X11::GLES_2_0_COMPATIBLE;
+ continue;
+ } else {
+ gl_initialization_error = true;
+ break;
+ }
+ }
+ }
+
+ if (opengl_api_type == ContextGL_X11::GLES_2_0_COMPATIBLE) {
+ if (RasterizerGLES2::is_viable() == OK) {
+ RasterizerGLES2::register_config();
+ RasterizerGLES2::make_current();
+ break;
+ } else {
+ gl_initialization_error = true;
+ break;
+ }
+ }
+ }
+
+ if (gl_initialization_error) {
+ OS::get_singleton()->alert("Your video card driver does not support any of the supported OpenGL versions.\n"
+ "Please update your drivers or if you have a very old or integrated GPU upgrade it.",
+ "Unable to initialize Video driver");
+ return ERR_UNAVAILABLE;
}
- video_driver_index = p_video_driver; // FIXME TODO - FIX IF DRIVER DETECTION HAPPENS AND GLES2 MUST BE USED
+ video_driver_index = p_video_driver;
context_gl->set_use_vsync(current_videomode.use_vsync);
@@ -339,8 +388,6 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
set_window_always_on_top(true);
}
- AudioDriverManager::initialize(p_audio_driver);
-
ERR_FAIL_COND_V(!visual_server, ERR_UNAVAILABLE);
ERR_FAIL_COND_V(x11_window == 0, ERR_UNAVAILABLE);
@@ -510,6 +557,8 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
visual_server->init();
+ AudioDriverManager::initialize(p_audio_driver);
+
input = memnew(InputDefault);
window_has_focus = true; // Set focus to true at init
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 8e31688d90..bd2253809c 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -598,12 +598,12 @@ real_t RigidBody2D::get_inertia() const {
void RigidBody2D::set_weight(real_t p_weight) {
- set_mass(p_weight / real_t(GLOBAL_DEF("physics/2d/default_gravity", 98)) / 10);
+ set_mass(p_weight / (real_t(GLOBAL_DEF("physics/2d/default_gravity", 98)) / 10));
}
real_t RigidBody2D::get_weight() const {
- return mass * real_t(GLOBAL_DEF("physics/2d/default_gravity", 98)) / 10;
+ return mass * (real_t(GLOBAL_DEF("physics/2d/default_gravity", 98)) / 10);
}
#ifndef DISABLE_DEPRECATED
diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp
index 09c36eb081..a71bacd3f6 100644
--- a/scene/animation/animation_node_state_machine.cpp
+++ b/scene/animation/animation_node_state_machine.cpp
@@ -390,7 +390,7 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *sm,
auto_advance = true;
}
- if (sm->transitions[i].from == current && sm->transitions[i].transition->has_auto_advance()) {
+ if (sm->transitions[i].from == current && auto_advance) {
if (sm->transitions[i].transition->get_priority() < priority_best) {
auto_advance_to = i;
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index b6d1916b2c..4727526b68 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -924,7 +924,7 @@ void SpatialMaterial::_update_shader() {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
- code += "\tvec4 detail_mask_tex = triplanar_texture(texture_detail_mask,uv1_power_normal);\n";
+ code += "\tvec4 detail_mask_tex = triplanar_texture(texture_detail_mask,uv1_power_normal,uv1_triplanar_pos);\n";
} else {
code += "\tvec4 detail_mask_tex = texture(texture_detail_mask,base_uv);\n";
}
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index 042cf28fec..e6ef956dc5 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -482,6 +482,11 @@ void Mesh::_bind_methods() {
ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2, "lightmap_size_hint"), "set_lightmap_size_hint", "get_lightmap_size_hint");
+ ClassDB::bind_method(D_METHOD("get_surface_count"), &Mesh::get_surface_count);
+ ClassDB::bind_method(D_METHOD("surface_get_arrays", "surf_idx"), &Mesh::surface_get_arrays);
+ ClassDB::bind_method(D_METHOD("surface_get_blend_shape_arrays", "surf_idx"), &Mesh::surface_get_blend_shape_arrays);
+ ClassDB::bind_method(D_METHOD("surface_get_material", "surf_idx"), &Mesh::surface_get_material);
+
BIND_ENUM_CONSTANT(PRIMITIVE_POINTS);
BIND_ENUM_CONSTANT(PRIMITIVE_LINES);
BIND_ENUM_CONSTANT(PRIMITIVE_LINE_STRIP);
@@ -1313,7 +1318,6 @@ void ArrayMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_blend_shape_mode"), &ArrayMesh::get_blend_shape_mode);
ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "compress_flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(ARRAY_COMPRESS_DEFAULT));
- ClassDB::bind_method(D_METHOD("get_surface_count"), &ArrayMesh::get_surface_count);
ClassDB::bind_method(D_METHOD("surface_remove", "surf_idx"), &ArrayMesh::surface_remove);
ClassDB::bind_method(D_METHOD("surface_update_region", "surf_idx", "offset", "data"), &ArrayMesh::surface_update_region);
ClassDB::bind_method(D_METHOD("surface_get_array_len", "surf_idx"), &ArrayMesh::surface_get_array_len);
@@ -1321,12 +1325,9 @@ void ArrayMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("surface_get_format", "surf_idx"), &ArrayMesh::surface_get_format);
ClassDB::bind_method(D_METHOD("surface_get_primitive_type", "surf_idx"), &ArrayMesh::surface_get_primitive_type);
ClassDB::bind_method(D_METHOD("surface_set_material", "surf_idx", "material"), &ArrayMesh::surface_set_material);
- ClassDB::bind_method(D_METHOD("surface_get_material", "surf_idx"), &ArrayMesh::surface_get_material);
ClassDB::bind_method(D_METHOD("surface_find_by_name", "name"), &ArrayMesh::surface_find_by_name);
ClassDB::bind_method(D_METHOD("surface_set_name", "surf_idx", "name"), &ArrayMesh::surface_set_name);
ClassDB::bind_method(D_METHOD("surface_get_name", "surf_idx"), &ArrayMesh::surface_get_name);
- ClassDB::bind_method(D_METHOD("surface_get_arrays", "surf_idx"), &ArrayMesh::surface_get_arrays);
- ClassDB::bind_method(D_METHOD("surface_get_blend_shape_arrays", "surf_idx"), &ArrayMesh::surface_get_blend_shape_arrays);
ClassDB::bind_method(D_METHOD("create_trimesh_shape"), &ArrayMesh::create_trimesh_shape);
ClassDB::bind_method(D_METHOD("create_convex_shape"), &ArrayMesh::create_convex_shape);
ClassDB::bind_method(D_METHOD("create_outline", "margin"), &ArrayMesh::create_outline);
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 1c082d9143..811e5c3d2c 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -2051,8 +2051,8 @@ void TextureLayered::create(uint32_t p_width, uint32_t p_height, uint32_t p_dept
width = p_width;
height = p_height;
depth = p_depth;
+
flags = p_flags;
- format = p_format;
}
void TextureLayered::set_layer_data(const Ref<Image> &p_image, int p_layer) {
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index c85f672ebf..8112d6be00 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -956,6 +956,8 @@ void TileSet::_bind_methods() {
ClassDB::bind_method(D_METHOD("tile_get_region", "id"), &TileSet::tile_get_region);
ClassDB::bind_method(D_METHOD("tile_set_shape", "id", "shape_id", "shape"), &TileSet::tile_set_shape);
ClassDB::bind_method(D_METHOD("tile_get_shape", "id", "shape_id"), &TileSet::tile_get_shape);
+ ClassDB::bind_method(D_METHOD("tile_set_shape_offset", "id", "shape_id", "shape_offset"), &TileSet::tile_set_shape_offset);
+ ClassDB::bind_method(D_METHOD("tile_get_shape_offset", "id", "shape_id"), &TileSet::tile_get_shape_offset);
ClassDB::bind_method(D_METHOD("tile_set_shape_transform", "id", "shape_id", "shape_transform"), &TileSet::tile_set_shape_transform);
ClassDB::bind_method(D_METHOD("tile_get_shape_transform", "id", "shape_id"), &TileSet::tile_get_shape_transform);
ClassDB::bind_method(D_METHOD("tile_set_shape_one_way", "id", "shape_id", "one_way"), &TileSet::tile_set_shape_one_way);
diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp
index b737f4681d..db178e0df8 100644
--- a/servers/audio_server.cpp
+++ b/servers/audio_server.cpp
@@ -185,9 +185,13 @@ void AudioDriverManager::initialize(int p_driver) {
if (drivers[i]->init() == OK) {
drivers[i]->set_singleton();
- return;
+ break;
}
}
+
+ if (driver_count > 1 && AudioDriver::get_singleton()->get_name() == "Dummy") {
+ WARN_PRINT("All audio drivers failed, falling back to the dummy driver.");
+ }
}
AudioDriver *AudioDriverManager::get_driver(int p_driver) {
diff --git a/thirdparty/cvtt/ConvectionKernels.cpp b/thirdparty/cvtt/ConvectionKernels.cpp
index 5137e35730..8d379344e1 100644
--- a/thirdparty/cvtt/ConvectionKernels.cpp
+++ b/thirdparty/cvtt/ConvectionKernels.cpp
@@ -1420,6 +1420,16 @@ namespace cvtt
return v;
}
+ static bool MakeBoolInt16(bool b)
+ {
+ return b;
+ }
+
+ static bool MakeBoolFloat(bool b)
+ {
+ return b;
+ }
+
static bool AndNot(bool a, bool b)
{
return a && !b;
diff --git a/thirdparty/libvpx/vpx_config.h b/thirdparty/libvpx/vpx_config.h
index fb9e13c4ad..6caec50c81 100644
--- a/thirdparty/libvpx/vpx_config.h
+++ b/thirdparty/libvpx/vpx_config.h
@@ -67,6 +67,12 @@
#define CONFIG_BIG_ENDIAN 0 //TODO: Autodetect
+#ifdef __EMSCRIPTEN__
+#define CONFIG_MULTITHREAD 0
+#else
+#define CONFIG_MULTITHREAD 1
+#endif
+
#ifdef _WIN32
#define HAVE_PTHREAD_H 0
#define HAVE_UNISTD_H 0
@@ -95,7 +101,6 @@
#define CONFIG_RUNTIME_CPU_DETECT 1
#define CONFIG_POSTPROC 0
#define CONFIG_VP9_POSTPROC 0
-#define CONFIG_MULTITHREAD 1
#define CONFIG_INTERNAL_STATS 0
#define CONFIG_VP8_ENCODER 0
#define CONFIG_VP8_DECODER 1
diff --git a/version.py b/version.py
index 0eff47acdc..558e2da56c 100644
--- a/version.py
+++ b/version.py
@@ -2,5 +2,5 @@ short_name = "godot"
name = "Godot Engine"
major = 3
minor = 1
-status = "dev"
+status = "alpha"
module_config = ""