diff options
64 files changed, 860 insertions, 204 deletions
diff --git a/core/image.cpp b/core/image.cpp index 4fc3b4becb..91c3d05a29 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -2632,6 +2632,9 @@ void Image::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "_set_data", "_get_data"); + BIND_CONSTANT(MAX_WIDTH); + BIND_CONSTANT(MAX_HEIGHT); + BIND_ENUM_CONSTANT(FORMAT_L8); //luminance BIND_ENUM_CONSTANT(FORMAT_LA8); //luminance-alpha BIND_ENUM_CONSTANT(FORMAT_R8); diff --git a/core/image.h b/core/image.h index 3604580e98..b23f8cac46 100644 --- a/core/image.h +++ b/core/image.h @@ -52,14 +52,14 @@ typedef Ref<Image> (*ImageMemLoadFunc)(const uint8_t *p_png, int p_size); class Image : public Resource { GDCLASS(Image, Resource); +public: + static SavePNGFunc save_png_func; + enum { MAX_WIDTH = 16384, // force a limit somehow MAX_HEIGHT = 16384 // force a limit somehow }; -public: - static SavePNGFunc save_png_func; - enum Format { FORMAT_L8, //luminance diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index b8bc24c1de..02e4d8dc7a 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -53,6 +53,12 @@ Error ResourceInteractiveLoader::wait() { return err; } +ResourceInteractiveLoader::~ResourceInteractiveLoader() { + if (path_loading != String()) { + ResourceLoader::_remove_from_loading_map(path_loading); + } +} + bool ResourceFormatLoader::recognize_path(const String &p_path, const String &p_for_type) const { String extension = p_path.get_extension(); @@ -280,6 +286,39 @@ RES ResourceLoader::_load(const String &p_path, const String &p_original_path, c return RES(); } +bool ResourceLoader::_add_to_loading_map(const String &p_path) { + + bool success; + if (loading_map_mutex) { + loading_map_mutex->lock(); + } + + if (loading_map.has(p_path)) { + success = false; + } else { + loading_map[p_path] = true; + success = true; + } + + if (loading_map_mutex) { + loading_map_mutex->unlock(); + } + + return success; +} + +void ResourceLoader::_remove_from_loading_map(const String &p_path) { + if (loading_map_mutex) { + loading_map_mutex->lock(); + } + + loading_map.erase(p_path); + + if (loading_map_mutex) { + loading_map_mutex->unlock(); + } +} + RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) { if (r_error) @@ -292,6 +331,15 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p local_path = ProjectSettings::get_singleton()->localize_path(p_path); if (!p_no_cache) { + + { + bool success = _add_to_loading_map(local_path); + if (!success) { + ERR_EXPLAIN("Resource: '" + local_path + "' is already being loaded. Cyclic reference?"); + ERR_FAIL_V(RES()); + } + } + //lock first if possible if (ResourceCache::lock) { ResourceCache::lock->read_lock(); @@ -310,7 +358,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p if (ResourceCache::lock) { ResourceCache::lock->read_unlock(); } - print_verbose("Loading resource: " + local_path + " (cached)"); + _remove_from_loading_map(local_path); return res; } } @@ -322,12 +370,21 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p bool xl_remapped = false; String path = _path_remap(local_path, &xl_remapped); - ERR_FAIL_COND_V(path == "", RES()); + if (path == "") { + if (!p_no_cache) { + _remove_from_loading_map(local_path); + } + ERR_EXPLAIN("Remapping '" + local_path + "'failed."); + ERR_FAIL_V(RES()); + } print_verbose("Loading resource: " + path); RES res = _load(path, local_path, p_type_hint, p_no_cache, r_error); if (res.is_null()) { + if (!p_no_cache) { + _remove_from_loading_map(local_path); + } return RES(); } if (!p_no_cache) @@ -346,6 +403,10 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p } #endif + if (!p_no_cache) { + _remove_from_loading_map(local_path); + } + if (_loaded_callback) { _loaded_callback(res, p_path); } @@ -394,19 +455,36 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_ else local_path = ProjectSettings::get_singleton()->localize_path(p_path); - if (!p_no_cache && ResourceCache::has(local_path)) { + if (!p_no_cache) { - print_verbose("Loading resource: " + local_path + " (cached)"); - Ref<Resource> res_cached = ResourceCache::get(local_path); - Ref<ResourceInteractiveLoaderDefault> ril = Ref<ResourceInteractiveLoaderDefault>(memnew(ResourceInteractiveLoaderDefault)); + bool success = _add_to_loading_map(local_path); + if (!success) { + ERR_EXPLAIN("Resource: '" + local_path + "' is already being loaded. Cyclic reference?"); + ERR_FAIL_V(RES()); + } - ril->resource = res_cached; - return ril; + if (ResourceCache::has(local_path)) { + + print_verbose("Loading resource: " + local_path + " (cached)"); + Ref<Resource> res_cached = ResourceCache::get(local_path); + Ref<ResourceInteractiveLoaderDefault> ril = Ref<ResourceInteractiveLoaderDefault>(memnew(ResourceInteractiveLoaderDefault)); + + ril->resource = res_cached; + ril->path_loading = local_path; + return ril; + } } bool xl_remapped = false; String path = _path_remap(local_path, &xl_remapped); - ERR_FAIL_COND_V(path == "", Ref<ResourceInteractiveLoader>()); + if (path == "") { + if (!p_no_cache) { + _remove_from_loading_map(local_path); + } + ERR_EXPLAIN("Remapping '" + local_path + "'failed."); + ERR_FAIL_V(RES()); + } + print_verbose("Loading resource: " + path); bool found = false; @@ -418,14 +496,21 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_ Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(path, local_path, r_error); if (ril.is_null()) continue; - if (!p_no_cache) + if (!p_no_cache) { ril->set_local_path(local_path); + ril->path_loading = local_path; + } + if (xl_remapped) ril->set_translation_remapped(true); return ril; } + if (!p_no_cache) { + _remove_from_loading_map(local_path); + } + if (found) { ERR_EXPLAIN("Failed loading resource: " + path); } else { @@ -833,6 +918,27 @@ void ResourceLoader::remove_custom_loaders() { } } +Mutex *ResourceLoader::loading_map_mutex = NULL; +HashMap<String, int> ResourceLoader::loading_map; + +void ResourceLoader::initialize() { +#ifndef NO_THREADS + loading_map_mutex = Mutex::create(); +#endif +} + +void ResourceLoader::finalize() { +#ifndef NO_THREADS + const String *K = NULL; + while ((K = loading_map.next(K))) { + ERR_PRINTS("Exited while resource is being loaded: " + *K); + } + loading_map.clear(); + memdelete(loading_map_mutex); + loading_map_mutex = NULL; +#endif +} + ResourceLoadErrorNotify ResourceLoader::err_notify = NULL; void *ResourceLoader::err_notify_ud = NULL; diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index 6c0e9d5554..622b74a998 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -40,6 +40,8 @@ class ResourceInteractiveLoader : public Reference { GDCLASS(ResourceInteractiveLoader, Reference); + friend class ResourceLoader; + String path_loading; protected: static void _bind_methods(); @@ -54,6 +56,7 @@ public: virtual Error wait(); ResourceInteractiveLoader() {} + ~ResourceInteractiveLoader(); }; class ResourceFormatLoader : public Reference { @@ -110,12 +113,18 @@ class ResourceLoader { static SelfList<Resource>::List remapped_list; friend class ResourceFormatImporter; + friend class ResourceInteractiveLoader; //internal load function static RES _load(const String &p_path, const String &p_original_path, const String &p_type_hint, bool p_no_cache, Error *r_error); static ResourceLoadedCallback _loaded_callback; static Ref<ResourceFormatLoader> _find_custom_resource_format_loader(String path); + static Mutex *loading_map_mutex; + static HashMap<String, int> loading_map; + + static bool _add_to_loading_map(const String &p_path); + static void _remove_from_loading_map(const String &p_path); public: static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL); @@ -170,6 +179,9 @@ public: static void remove_custom_resource_format_loader(String script_path); static void add_custom_loaders(); static void remove_custom_loaders(); + + static void initialize(); + static void finalize(); }; #endif diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index a31aa9cb01..60c2778603 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -99,6 +99,7 @@ void register_core_types() { _global_mutex = Mutex::create(); StringName::setup(); + ResourceLoader::initialize(); register_global_constants(); register_variant_methods(); @@ -269,6 +270,8 @@ void unregister_core_types() { if (ip) memdelete(ip); + ResourceLoader::finalize(); + ObjectDB::cleanup(); unregister_variant_methods(); diff --git a/doc/classes/EditorSpatialGizmo.xml b/doc/classes/EditorSpatialGizmo.xml index c3ecd3c3b7..45b92276f1 100644 --- a/doc/classes/EditorSpatialGizmo.xml +++ b/doc/classes/EditorSpatialGizmo.xml @@ -4,7 +4,7 @@ Custom gizmo for editing Spatial objects. </brief_description> <description> - Custom gizmo that is used for providing custom visualization and editing (handles) for 3D Spatial objects. These are created by [method EditorSpatialGizmoPlugin.create_gizmo]. + Custom gizmo that is used for providing custom visualization and editing (handles) for 3D Spatial objects. See [EditorSpatialGizmoPlugin] for more information. </description> <tutorials> </tutorials> @@ -116,7 +116,30 @@ <argument index="0" name="index" type="int"> </argument> <description> - Get actual value of a handle. This value can be anything and used for eventually undoing the motion when calling [method commit_handle] + Get actual value of a handle. This value can be anything and used for eventually undoing the motion when calling [method commit_handle]. + </description> + </method> + <method name="get_plugin" qualifiers="const"> + <return type="EditorSpatialGizmoPlugin"> + </return> + <description> + Return the [EditorSpatialGizmoPlugin] that owns this gizmo. It's useful to retrieve materials using [method EditorSpatialGizmoPlugin.get_material]. + </description> + </method> + <method name="get_spatial_node" qualifiers="const"> + <return type="Spatial"> + </return> + <description> + Returns the Spatial node associated with this gizmo. + </description> + </method> + <method name="is_handle_highlighted" qualifiers="virtual"> + <return type="bool"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + Get whether a handle is highlighted or not. </description> </method> <method name="redraw" qualifiers="virtual"> diff --git a/doc/classes/EditorSpatialGizmoPlugin.xml b/doc/classes/EditorSpatialGizmoPlugin.xml index 521ec748b3..a62b23ead8 100644 --- a/doc/classes/EditorSpatialGizmoPlugin.xml +++ b/doc/classes/EditorSpatialGizmoPlugin.xml @@ -1,10 +1,13 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="EditorSpatialGizmoPlugin" inherits="Resource" category="Core" version="3.1"> <brief_description> + Used by the editor to define Spatial gizmo types. </brief_description> <description> + EditorSpatialGizmoPlugin allows you to define a new type of Gizmo. There are two main ways to do so: extending [EditorSpatialGizmoPlugin] for the simpler gizmos, or creating a new [EditorSpatialGizmo] type. See the tutorial in the documentation for more info. </description> <tutorials> + <link>https://docs.godotengine.org/en/latest/tutorials/plugins/editor/spatial_gizmos.html</link> </tutorials> <demos> </demos> @@ -17,12 +20,14 @@ <argument index="1" name="material" type="SpatialMaterial"> </argument> <description> + Adds a new material to the internal material list for the plugin. It can then be accessed with [method get_material]. Should not be overridden. </description> </method> <method name="can_be_hidden" qualifiers="virtual"> <return type="bool"> </return> <description> + Override this method to define whether the gizmo can be hidden or not. Defaults to true. </description> </method> <method name="commit_handle" qualifiers="virtual"> @@ -37,6 +42,7 @@ <argument index="3" name="cancel" type="bool" default="false"> </argument> <description> + Override this method to commit gizmo handles. Called for this plugin's active gizmos. </description> </method> <method name="create_gizmo" qualifiers="virtual"> @@ -45,6 +51,7 @@ <argument index="0" name="spatial" type="Spatial"> </argument> <description> + Override this method to return a custom [EditorSpatialGizmo] for the spatial nodes of your choice, return [code]null[/code] for the rest of nodes. (See also [method has_gizmo]) </description> </method> <method name="create_handle_material"> @@ -55,6 +62,7 @@ <argument index="1" name="billboard" type="bool" default="false"> </argument> <description> + Creates a handle material with its variants (selected and/or editable) and adds them to the internal material list. They can then be accessed with [method get_material] and used in [method EditorSpatialGizmo.add_handles]. Should not be overridden. </description> </method> <method name="create_icon_material"> @@ -69,6 +77,7 @@ <argument index="3" name="color" type="Color" default="Color( 1, 1, 1, 1 )"> </argument> <description> + Creates an icon material with its variants (selected and/or editable) and adds them to the internal material list. They can then be accessed with [method get_material] and used in [method EditorSpatialGizmo.add_unscaled_billboard]. Should not be overridden. </description> </method> <method name="create_material"> @@ -85,6 +94,7 @@ <argument index="4" name="use_vertex_color" type="bool" default="false"> </argument> <description> + Creates an unshaded material with its variants (selected and/or editable) and adds them to the internal material list. They can then be accessed with [method get_material] and used in [method EditorSpatialGizmo.add_mesh] and [method EditorSpatialGizmo.add_lines]. Should not be overridden. </description> </method> <method name="get_handle_name" qualifiers="virtual"> @@ -95,6 +105,7 @@ <argument index="1" name="index" type="int"> </argument> <description> + Override this method to provide gizmo's handle names. Called for this plugin's active gizmos. </description> </method> <method name="get_handle_value" qualifiers="virtual"> @@ -105,6 +116,7 @@ <argument index="1" name="index" type="int"> </argument> <description> + Get actual value of a handle from gizmo. Called for this plugin's active gizmos. </description> </method> <method name="get_material"> @@ -115,12 +127,14 @@ <argument index="1" name="gizmo" type="EditorSpatialGizmo"> </argument> <description> + Get material from the internal list of materials. If an [EditorSpatialGizmo] is provided it will try to get the corresponding variant (selected and/or editable). </description> </method> <method name="get_name" qualifiers="virtual"> <return type="String"> </return> <description> + Override this method to provide the name that will appear in teh gizmo visibility menu. </description> </method> <method name="has_gizmo" qualifiers="virtual"> @@ -129,9 +143,10 @@ <argument index="0" name="spatial" type="Spatial"> </argument> <description> + Override this method to define which Spatial nodes have a gizmo from this plugin. Whenever a [Spatial] node is added to a scene this method is called, if it returns [code]true[/code] the node gets a generic [EditorSpatialGizmo] assigned and is added to this plugin's list of active gizmos. </description> </method> - <method name="is_gizmo_handle_highlighted" qualifiers="virtual"> + <method name="is_handle_highlighted" qualifiers="virtual"> <return type="bool"> </return> <argument index="0" name="gizmo" type="EditorSpatialGizmo"> @@ -139,12 +154,14 @@ <argument index="1" name="index" type="int"> </argument> <description> + Get whether a handle is highlighted or not. Called for this plugin's active gizmos. </description> </method> <method name="is_selectable_when_hidden" qualifiers="virtual"> <return type="bool"> </return> <description> + Override this method to define whether Spatial with this gizmo should be selecteble even when the gizmo is hidden. </description> </method> <method name="redraw" qualifiers="virtual"> @@ -153,6 +170,7 @@ <argument index="0" name="gizmo" type="EditorSpatialGizmo"> </argument> <description> + Callback to redraw the provided gizmo. Called for this plugin's active gizmos. </description> </method> <method name="set_handle" qualifiers="virtual"> @@ -167,6 +185,7 @@ <argument index="3" name="point" type="Vector2"> </argument> <description> + Update the value of a handle after it has been updated. Called for this plugin's active gizmos. </description> </method> </methods> diff --git a/doc/classes/Expression.xml b/doc/classes/Expression.xml index c5f71fe55e..b0a21d7f82 100644 --- a/doc/classes/Expression.xml +++ b/doc/classes/Expression.xml @@ -16,7 +16,7 @@ func _on_text_entered(command): var error = expression.parse(command, []) if error != OK: - print(get_error_text()) + print(expression.get_error_text()) return var result = expression.execute([], null, true) if not expression.has_execute_failed(): diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml index 56accdcd9e..8868dd778d 100644 --- a/doc/classes/Image.xml +++ b/doc/classes/Image.xml @@ -4,7 +4,7 @@ Image datatype. </brief_description> <description> - Native image datatype. Contains image data, which can be converted to a [Texture], and several functions to interact with it. The maximum width and height for an [code]Image[/code] is 16384 pixels. + Native image datatype. Contains image data, which can be converted to a [Texture], and several functions to interact with it. The maximum width and height for an [code]Image[/code] are [constant MAX_WIDTH] and [constant MAX_HEIGHT]. </description> <tutorials> </tutorials> @@ -476,6 +476,12 @@ </member> </members> <constants> + <constant name="MAX_WIDTH" value="16384"> + The maximal width allowed for [code]Image[/code] resources. + </constant> + <constant name="MAX_HEIGHT" value="16384"> + The maximal height allowed for [code]Image[/code] resources. + </constant> <constant name="FORMAT_L8" value="0" enum="Format"> </constant> <constant name="FORMAT_LA8" value="1" enum="Format"> diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h index ddc0dd5fa9..214da82819 100644 --- a/drivers/dummy/rasterizer_dummy.h +++ b/drivers/dummy/rasterizer_dummy.h @@ -241,6 +241,7 @@ public: void textures_keep_original(bool p_enable) {} void texture_set_proxy(RID p_proxy, RID p_base) {} + virtual Size2 texture_size_with_proxy(RID p_texture) const { return Size2(); } void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) {} /* SKY API */ diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp index 6f686690bf..64e4dbdab4 100644 --- a/drivers/gles2/rasterizer_canvas_gles2.cpp +++ b/drivers/gles2/rasterizer_canvas_gles2.cpp @@ -112,9 +112,11 @@ void RasterizerCanvasGLES2::_set_uniforms() { void RasterizerCanvasGLES2::canvas_begin() { state.canvas_shader.bind(); + bool transparent = false; if (storage->frame.current_rt) { glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo); glColorMask(1, 1, 1, 1); + transparent = storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]; } if (storage->frame.clear_request) { @@ -122,11 +124,13 @@ void RasterizerCanvasGLES2::canvas_begin() { glClearColor(storage->frame.clear_request_color.r, storage->frame.clear_request_color.g, storage->frame.clear_request_color.b, - storage->frame.clear_request_color.a); + transparent ? storage->frame.clear_request_color.a : 1.0); glClear(GL_COLOR_BUFFER_BIT); storage->frame.clear_request = false; } + glColorMask(1, 1, 1, transparent ? 1 : 0); + /* if (storage->frame.current_rt) { glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo); @@ -182,6 +186,7 @@ void RasterizerCanvasGLES2::canvas_end() { state.using_texture_rect = false; state.using_skeleton = false; state.using_ninepatch = false; + glColorMask(1, 1, 1, 1); } RasterizerStorageGLES2::Texture *RasterizerCanvasGLES2::_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map) { diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp index ae677b606d..2c52895bda 100644 --- a/drivers/gles2/rasterizer_scene_gles2.cpp +++ b/drivers/gles2/rasterizer_scene_gles2.cpp @@ -998,6 +998,7 @@ void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::G //add element to opaque RenderList::Element *eo = render_list.add_element(); *eo = *e; + eo->use_accum_ptr = &eo->use_accum; } int rpsize = e->instance->reflection_probe_instances.size(); @@ -2066,6 +2067,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements, bool prev_unshaded = false; bool prev_instancing = false; + bool prev_depth_prepass = false; state.scene_shader.set_conditional(SceneShaderGLES2::SHADELESS, false); RasterizerStorageGLES2::Material *prev_material = NULL; RasterizerStorageGLES2::Geometry *prev_geometry = NULL; @@ -2141,6 +2143,19 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements, prev_unshaded = unshaded; } + bool depth_prepass = false; + + if (!p_alpha_pass && material->shader && material->shader->spatial.depth_draw_mode == RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) { + depth_prepass = true; + } + + if (depth_prepass != prev_depth_prepass) { + + state.scene_shader.set_conditional(SceneShaderGLES2::USE_DEPTH_PREPASS, depth_prepass); + prev_depth_prepass = depth_prepass; + rebind = true; + } + bool base_pass = !accum_pass && !unshaded; //conditions for a base pass if (base_pass != prev_base_pass) { @@ -2432,6 +2447,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements, state.scene_shader.set_conditional(SceneShaderGLES2::USE_LIGHTMAP_CAPTURE, false); state.scene_shader.set_conditional(SceneShaderGLES2::FOG_DEPTH_ENABLED, false); state.scene_shader.set_conditional(SceneShaderGLES2::FOG_HEIGHT_ENABLED, false); + state.scene_shader.set_conditional(SceneShaderGLES2::USE_RADIANCE_MAP, false); } void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_custom_fov, float p_energy, const Basis &p_sky_orientation) { diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index 0f52a02363..d00d572ccf 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -846,6 +846,17 @@ void RasterizerStorageGLES2::textures_keep_original(bool p_enable) { config.keep_original_textures = p_enable; } +Size2 RasterizerStorageGLES2::texture_size_with_proxy(RID p_texture) const { + + const Texture *texture = texture_owner.getornull(p_texture); + ERR_FAIL_COND_V(!texture, Size2()); + if (texture->proxy) { + return Size2(texture->proxy->width, texture->proxy->height); + } else { + return Size2(texture->width, texture->height); + } +} + void RasterizerStorageGLES2::texture_set_proxy(RID p_texture, RID p_proxy) { Texture *texture = texture_owner.getornull(p_texture); ERR_FAIL_COND(!texture); diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h index ed21238db6..ba48ddd185 100644 --- a/drivers/gles2/rasterizer_storage_gles2.h +++ b/drivers/gles2/rasterizer_storage_gles2.h @@ -342,6 +342,7 @@ public: virtual void textures_keep_original(bool p_enable); virtual void texture_set_proxy(RID p_texture, RID p_proxy); + virtual Size2 texture_size_with_proxy(RID p_texture) const; virtual void texture_set_detect_3d_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata); virtual void texture_set_detect_srgb_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata); diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp index bff031b93a..fa1242ceed 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/drivers/gles2/shader_compiler_gles2.cpp @@ -806,9 +806,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { actions[VS::SHADER_CANVAS_ITEM].usage_defines["SCREEN_PIXEL_SIZE"] = "@SCREEN_UV"; actions[VS::SHADER_CANVAS_ITEM].usage_defines["NORMAL"] = "#define NORMAL_USED\n"; actions[VS::SHADER_CANVAS_ITEM].usage_defines["NORMALMAP"] = "#define NORMALMAP_USED\n"; - actions[VS::SHADER_CANVAS_ITEM].usage_defines["SHADOW_COLOR"] = "#define SHADOW_COLOR_USED\n"; actions[VS::SHADER_CANVAS_ITEM].usage_defines["LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n"; - actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n"; /** SPATIAL SHADER **/ @@ -831,7 +829,6 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { actions[VS::SHADER_SPATIAL].renames["POINT_SIZE"] = "gl_PointSize"; // gl_InstanceID is not available in OpenGL ES 2.0 actions[VS::SHADER_SPATIAL].renames["INSTANCE_ID"] = "0"; - actions[VS::SHADER_SPATIAL].renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB"; //builtins @@ -863,12 +860,15 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"] = "screen_uv"; actions[VS::SHADER_SPATIAL].renames["SCREEN_TEXTURE"] = "screen_texture"; actions[VS::SHADER_SPATIAL].renames["DEPTH_TEXTURE"] = "depth_buffer"; - actions[VS::SHADER_SPATIAL].renames["SIDE"] = "side"; + // Defined in GLES3, but not available in GLES2 + //actions[VS::SHADER_SPATIAL].renames["DEPTH"] = "gl_FragDepth"; actions[VS::SHADER_SPATIAL].renames["ALPHA_SCISSOR"] = "alpha_scissor"; + actions[VS::SHADER_SPATIAL].renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB"; //for light actions[VS::SHADER_SPATIAL].renames["VIEW"] = "view"; actions[VS::SHADER_SPATIAL].renames["LIGHT_COLOR"] = "light_color"; + actions[VS::SHADER_SPATIAL].renames["LIGHT"] = "light"; actions[VS::SHADER_SPATIAL].renames["ATTENUATION"] = "attenuation"; actions[VS::SHADER_SPATIAL].renames["DIFFUSE_LIGHT"] = "diffuse_light"; actions[VS::SHADER_SPATIAL].renames["SPECULAR_LIGHT"] = "specular_light"; @@ -903,6 +903,12 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { actions[VS::SHADER_SPATIAL].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["world_vertex_coords"] = "#define VERTEX_WORLD_COORDS_USED\n"; + // Defined in GLES3, could be implemented in GLES2 too if there's a need for it + //actions[VS::SHADER_SPATIAL].render_mode_defines["ensure_correct_normals"] = "#define ENSURE_CORRECT_NORMALS\n"; + // Defined in GLES3, might not be possible in GLES2 as gl_FrontFacing is not available + //actions[VS::SHADER_SPATIAL].render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n"; + //actions[VS::SHADER_SPATIAL].render_mode_defines["cull_disabled"] = "#define DO_SIDE_CHECK\n"; + bool force_lambert = GLOBAL_GET("rendering/quality/shading/force_lambert_over_burley"); if (!force_lambert) { @@ -928,27 +934,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { actions[VS::SHADER_SPATIAL].render_mode_defines["shadows_disabled"] = "#define SHADOWS_DISABLED\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n"; - /* PARTICLES SHADER */ - - actions[VS::SHADER_PARTICLES].renames["COLOR"] = "out_color"; - actions[VS::SHADER_PARTICLES].renames["VELOCITY"] = "out_velocity_active.xyz"; - actions[VS::SHADER_PARTICLES].renames["MASS"] = "mass"; - actions[VS::SHADER_PARTICLES].renames["ACTIVE"] = "shader_active"; - actions[VS::SHADER_PARTICLES].renames["RESTART"] = "restart"; - actions[VS::SHADER_PARTICLES].renames["CUSTOM"] = "out_custom"; - actions[VS::SHADER_PARTICLES].renames["TRANSFORM"] = "xform"; - actions[VS::SHADER_PARTICLES].renames["TIME"] = "time"; - actions[VS::SHADER_PARTICLES].renames["LIFETIME"] = "lifetime"; - actions[VS::SHADER_PARTICLES].renames["DELTA"] = "local_delta"; - actions[VS::SHADER_PARTICLES].renames["NUMBER"] = "particle_number"; - actions[VS::SHADER_PARTICLES].renames["INDEX"] = "index"; - actions[VS::SHADER_PARTICLES].renames["GRAVITY"] = "current_gravity"; - actions[VS::SHADER_PARTICLES].renames["EMISSION_TRANSFORM"] = "emission_transform"; - actions[VS::SHADER_PARTICLES].renames["RANDOM_SEED"] = "random_seed"; - - actions[VS::SHADER_PARTICLES].render_mode_defines["disable_force"] = "#define DISABLE_FORCE\n"; - actions[VS::SHADER_PARTICLES].render_mode_defines["disable_velocity"] = "#define DISABLE_VELOCITY\n"; - actions[VS::SHADER_PARTICLES].render_mode_defines["keep_data"] = "#define ENABLE_KEEP_DATA\n"; + // No defines for particle shaders in GLES2, there are no GPU particles vertex_name = "vertex"; fragment_name = "fragment"; diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl index c7f5c97133..6c3d3baccd 100644 --- a/drivers/gles2/shaders/scene.glsl +++ b/drivers/gles2/shaders/scene.glsl @@ -1498,6 +1498,12 @@ FRAGMENT_SHADER_CODE } #endif +#ifdef USE_DEPTH_PREPASS + if (alpha < 0.99) { + discard; + } +#endif + #ifdef BASE_PASS //none #ifdef USE_RADIANCE_MAP diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 79fec63db0..b8f0965af8 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -146,10 +146,15 @@ void RasterizerCanvasGLES3::canvas_begin() { if (storage->frame.current_rt && storage->frame.clear_request) { // a clear request may be pending, so do it + bool transparent = storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]; - glClearColor(storage->frame.clear_request_color.r, storage->frame.clear_request_color.g, storage->frame.clear_request_color.b, storage->frame.clear_request_color.a); + glClearColor(storage->frame.clear_request_color.r, + storage->frame.clear_request_color.g, + storage->frame.clear_request_color.b, + transparent ? storage->frame.clear_request_color.a : 1.0); glClear(GL_COLOR_BUFFER_BIT); storage->frame.clear_request = false; + glColorMask(1, 1, 1, transparent ? 1 : 0); } reset_canvas(); @@ -193,6 +198,7 @@ void RasterizerCanvasGLES3::canvas_end() { glBindVertexArray(0); glBindBufferBase(GL_UNIFORM_BUFFER, 0, 0); + glColorMask(1, 1, 1, 1); state.using_texture_rect = false; state.using_ninepatch = false; diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 70037dfc33..4ef7db8ea9 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -112,15 +112,6 @@ void glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid }, target, offset, data, size); /* clang-format on */ } - -void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data) { - - /* clang-format off */ - EM_ASM({ - GLctx.bufferSubData($0, $1, HEAPU8, $2, $3); - }, target, offset, data, size); - /* clang-format on */ -} #endif void glTexStorage2DCustom(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type) { @@ -1687,6 +1678,17 @@ RID RasterizerStorageGLES3::texture_create_radiance_cubemap(RID p_source, int p_ return texture_owner.make_rid(ctex); } +Size2 RasterizerStorageGLES3::texture_size_with_proxy(RID p_texture) const { + + const Texture *texture = texture_owner.getornull(p_texture); + ERR_FAIL_COND_V(!texture, Size2()); + if (texture->proxy) { + return Size2(texture->proxy->width, texture->proxy->height); + } else { + return Size2(texture->width, texture->height); + } +} + void RasterizerStorageGLES3::texture_set_proxy(RID p_texture, RID p_proxy) { Texture *texture = texture_owner.get(p_texture); diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 811f9c8d80..88897e1e07 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -46,7 +46,6 @@ // WebGL 2.0 has no MapBufferRange/UnmapBuffer, but offers a non-ES style BufferSubData API instead. #ifdef __EMSCRIPTEN__ void glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data); -void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); #endif class RasterizerCanvasGLES3; @@ -375,6 +374,8 @@ public: virtual void texture_set_detect_normal_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata); virtual void texture_set_proxy(RID p_texture, RID p_proxy); + virtual Size2 texture_size_with_proxy(RID p_texture) const; + virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable); /* SKY API */ diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index cda6dac506..4d6f37e093 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -963,9 +963,9 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_PARTICLES].renames["EMISSION_TRANSFORM"] = "emission_transform"; actions[VS::SHADER_PARTICLES].renames["RANDOM_SEED"] = "random_seed"; - actions[VS::SHADER_SPATIAL].render_mode_defines["disable_force"] = "#define DISABLE_FORCE\n"; - actions[VS::SHADER_SPATIAL].render_mode_defines["disable_velocity"] = "#define DISABLE_VELOCITY\n"; - actions[VS::SHADER_SPATIAL].render_mode_defines["keep_data"] = "#define ENABLE_KEEP_DATA\n"; + actions[VS::SHADER_PARTICLES].render_mode_defines["disable_force"] = "#define DISABLE_FORCE\n"; + actions[VS::SHADER_PARTICLES].render_mode_defines["disable_velocity"] = "#define DISABLE_VELOCITY\n"; + actions[VS::SHADER_PARTICLES].render_mode_defines["keep_data"] = "#define ENABLE_KEEP_DATA\n"; vertex_name = "vertex"; fragment_name = "fragment"; diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index d7e0302478..1078fabc2e 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -2010,7 +2010,7 @@ void EditorInspector::_property_changed(const String &p_path, const Variant &p_v } } -void EditorInspector::_property_changed_update_all(const String &p_path, const Variant &p_value) { +void EditorInspector::_property_changed_update_all(const String &p_path, const Variant &p_value, const String &p_name, bool p_changing) { update_tree(); } diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index 4fb3198e87..3d22cdb9a3 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -302,7 +302,7 @@ class EditorInspector : public ScrollContainer { void _edit_set(const String &p_name, const Variant &p_value, bool p_refresh_all, const String &p_changed_field); void _property_changed(const String &p_path, const Variant &p_value, const String &p_name = "", bool changing = false); - void _property_changed_update_all(const String &p_path, const Variant &p_value); + void _property_changed_update_all(const String &p_path, const Variant &p_value, const String &p_name = "", bool p_changing = false); void _multiple_properties_changed(Vector<String> p_paths, Array p_values); void _property_keyed(const String &p_path, bool p_advance); void _property_keyed_with_value(const String &p_path, const Variant &p_value, bool p_advance); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 0ff0bca7ee..c8e00b0586 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -952,6 +952,9 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) { } if (img.is_valid()) { + + img = img->duplicate(); + save.step(TTR("Creating Thumbnail"), 2); save.step(TTR("Creating Thumbnail"), 3); @@ -5635,7 +5638,7 @@ EditorNode::EditorNode() { bottom_panel->add_child(bottom_panel_vb); bottom_panel_hb = memnew(HBoxContainer); - bottom_panel_hb->set_custom_minimum_size(Size2(0, 24)); // Adjust for the height of the "Expand Bottom Dock" icon. + bottom_panel_hb->set_custom_minimum_size(Size2(0, 24 * EDSCALE)); // Adjust for the height of the "Expand Bottom Dock" icon. bottom_panel_vb->add_child(bottom_panel_hb); bottom_panel_hb_editors = memnew(HBoxContainer); diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index f19eac6878..56bab440c9 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -2187,7 +2187,19 @@ void EditorPropertyResource::_menu_option(int p_which) { return; } - Object *obj = ClassDB::instance(intype); + Object *obj = NULL; + + if (ScriptServer::is_global_class(intype)) { + obj = ClassDB::instance(ScriptServer::get_global_class_base(intype)); + if (obj) { + Ref<Script> script = ResourceLoader::load(ScriptServer::get_global_class_path(intype)); + if (script.is_valid()) { + obj->set_script(Variant(script)); + } + } + } else { + obj = ClassDB::instance(intype); + } if (!obj) { obj = EditorNode::get_editor_data().instance_custom_type(intype, "Resource"); diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp index 368efbc48f..f77f31db80 100644 --- a/editor/editor_resource_preview.cpp +++ b/editor/editor_resource_preview.cpp @@ -159,6 +159,7 @@ void EditorResourcePreview::_generate_preview(Ref<ImageTexture> &r_texture, Ref< small_thumbnail_size *= EDSCALE; Ref<Image> small_image = r_texture->get_data(); + small_image = small_image->duplicate(); small_image->resize(small_thumbnail_size, small_thumbnail_size, Image::INTERPOLATE_CUBIC); r_small_texture.instance(); r_small_texture->create_from_image(small_image); diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp index cd5df14f1b..dbf63102cf 100644 --- a/editor/import/editor_import_collada.cpp +++ b/editor/import/editor_import_collada.cpp @@ -44,8 +44,6 @@ #include "scene/resources/packed_scene.h" #include "scene/resources/surface_tool.h" -#include <iostream> - struct ColladaImport { Collada collada; diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index a42765df6b..c68023ee9b 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -174,6 +174,7 @@ void EditorAssetLibraryItemDescription::set_image(int p_type, int p_index, const if (preview_images[i].is_video) { Ref<Image> overlay = get_icon("PlayOverlay", "EditorIcons")->get_data(); Ref<Image> thumbnail = p_image->get_data(); + thumbnail = thumbnail->duplicate(); Point2 overlay_pos = Point2((thumbnail->get_width() - overlay->get_width()) / 2, (thumbnail->get_height() - overlay->get_height()) / 2); thumbnail->lock(); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 2913c4ce56..b2d2704f07 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -2741,10 +2741,11 @@ void CanvasItemEditor::_draw_selection() { if (canvas_item->_edit_use_pivot()) { // Draw the node's pivot - Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * Transform2D(canvas_item->_edit_get_rotation(), canvas_item->_edit_get_position())).orthonormalized(); + Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * Transform2D(canvas_item->_edit_get_rotation(), canvas_item->_edit_get_position() + canvas_item->_edit_get_pivot())).orthonormalized(); Transform2D simple_xform = viewport->get_transform() * unscaled_transform; + viewport->draw_set_transform_matrix(simple_xform); - viewport->draw_texture(pivot_icon, canvas_item->_edit_get_pivot() - (pivot_icon->get_size() / 2).floor()); + viewport->draw_texture(pivot_icon, -(pivot_icon->get_size() / 2).floor()); viewport->draw_set_transform_matrix(viewport->get_transform()); } @@ -3277,7 +3278,24 @@ void CanvasItemEditor::_notification(int p_what) { pivot_button->set_disabled(nb_having_pivot == 0); // Show / Hide the layout button - presets_menu->set_visible(nb_control > 0 && nb_control == selection.size()); + if (nb_control > 0 && nb_control == selection.size()) { + presets_menu->set_visible(true); + presets_menu->set_tooltip(TTR("Presets for the anchors and margins values of a Control node.")); + + // Disable if the selected node is child of a container + presets_menu->set_disabled(false); + for (List<CanvasItem *>::Element *E = selection.front(); E; E = E->next()) { + Control *control = Object::cast_to<Control>(E->get()); + if (!control || Object::cast_to<Container>(control->get_parent())) { + presets_menu->set_disabled(true); + presets_menu->set_tooltip(TTR("A child of a container gets its anchors and margins values overriden by its parent.")); + break; + } + } + + } else { + presets_menu->set_visible(false); + } // Update the viewport if bones changes for (Map<BoneKey, BoneList>::Element *E = bone_list.front(); E; E = E->next()) { diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index 8464dfd0aa..0c0cc9d635 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -99,12 +99,14 @@ Ref<Texture> EditorTexturePreviewPlugin::generate(const RES &p_from, const Size2 } else { Ref<Texture> tex = p_from; img = tex->get_data(); + if (img.is_valid()) { + img = img->duplicate(); + } } if (img.is_null() || img->empty()) return Ref<Texture>(); - img = img->duplicate(); img->clear_mipmaps(); if (img->is_compressed()) { @@ -332,7 +334,7 @@ Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES &p_from, const Size OS::get_singleton()->delay_usec(10); } - Ref<Image> img = VS::get_singleton()->VS::get_singleton()->texture_get_data(viewport_texture); + Ref<Image> img = VS::get_singleton()->texture_get_data(viewport_texture); VS::get_singleton()->mesh_surface_set_material(sphere, 0, RID()); ERR_FAIL_COND_V(!img.is_valid(), Ref<ImageTexture>()); @@ -732,7 +734,7 @@ Ref<Texture> EditorMeshPreviewPlugin::generate(const RES &p_from, const Size2 p_ OS::get_singleton()->delay_usec(10); } - Ref<Image> img = VS::get_singleton()->VS::get_singleton()->texture_get_data(viewport_texture); + Ref<Image> img = VS::get_singleton()->texture_get_data(viewport_texture); ERR_FAIL_COND_V(img.is_null(), Ref<ImageTexture>()); VS::get_singleton()->instance_set_base(mesh_instance, RID()); @@ -852,7 +854,7 @@ Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path, c OS::get_singleton()->delay_usec(10); } - Ref<Image> img = VS::get_singleton()->VS::get_singleton()->texture_get_data(viewport_texture); + Ref<Image> img = VS::get_singleton()->texture_get_data(viewport_texture); ERR_FAIL_COND_V(img.is_null(), Ref<ImageTexture>()); img->convert(Image::FORMAT_RGBA8); diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index 276ca2e451..78bc989c5f 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -5732,6 +5732,7 @@ void SpatialEditorPlugin::snap_cursor_to_plane(const Plane &p_plane) { } void SpatialEditor::add_gizmo_plugin(Ref<EditorSpatialGizmoPlugin> p_plugin) { + ERR_FAIL_NULL(p_plugin.ptr()); gizmo_plugins.push_back(p_plugin); _update_gizmos_menu(); SpatialEditor::get_singleton()->update_all_gizmos(); @@ -5869,7 +5870,7 @@ Ref<SpatialMaterial> EditorSpatialGizmoPlugin::get_material(const String &p_name ERR_FAIL_COND_V(!materials.has(p_name), Ref<SpatialMaterial>()); ERR_FAIL_COND_V(materials[p_name].size() == 0, Ref<SpatialMaterial>()); - if (p_gizmo.is_null()) return materials[p_name][0]; + if (p_gizmo.is_null() || materials[p_name].size() == 1) return materials[p_name][0]; int index = (p_gizmo->is_selected() ? 1 : 0) + (p_gizmo->is_editable() ? 2 : 0); @@ -5888,7 +5889,7 @@ String EditorSpatialGizmoPlugin::get_name() const { if (get_script_instance() && get_script_instance()->has_method("get_name")) { return get_script_instance()->call("get_name"); } - return TTR("Name-less gizmo"); + return TTR("Nameless gizmo"); } Ref<EditorSpatialGizmo> EditorSpatialGizmoPlugin::get_gizmo(Spatial *p_spatial) { @@ -5938,7 +5939,7 @@ void EditorSpatialGizmoPlugin::_bind_methods() { cm.default_arguments.push_back(false); BIND_VMETHOD(cm); - BIND_VMETHOD(MethodInfo(Variant::BOOL, "is_gizmo_handle_highlighted", GIZMO_REF, PropertyInfo(Variant::INT, "index"))); + BIND_VMETHOD(MethodInfo(Variant::BOOL, "is_handle_highlighted", GIZMO_REF, PropertyInfo(Variant::INT, "index"))); #undef GIZMO_REF } @@ -6008,9 +6009,9 @@ void EditorSpatialGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_ } } -bool EditorSpatialGizmoPlugin::is_gizmo_handle_highlighted(const EditorSpatialGizmo *p_gizmo, int p_idx) const { - if (get_script_instance() && get_script_instance()->has_method("is_gizmo_handle_highlighted")) { - return get_script_instance()->call("is_gizmo_handle_highlighted", p_gizmo, p_idx); +bool EditorSpatialGizmoPlugin::is_handle_highlighted(const EditorSpatialGizmo *p_gizmo, int p_idx) const { + if (get_script_instance() && get_script_instance()->has_method("is_handle_highlighted")) { + return get_script_instance()->call("is_handle_highlighted", p_gizmo, p_idx); } return false; } diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h index 87cd089428..2dc627cb27 100644 --- a/editor/plugins/spatial_editor_plugin.h +++ b/editor/plugins/spatial_editor_plugin.h @@ -110,6 +110,7 @@ public: void add_handles(const Vector<Vector3> &p_handles, const Ref<Material> &p_material, bool p_billboard = false, bool p_secondary = false); void add_solid_box(Ref<Material> &p_material, Vector3 p_size, Vector3 p_position = Vector3()); + virtual bool is_handle_highlighted(int p_idx) const; virtual String get_handle_name(int p_idx) const; virtual Variant get_handle_value(int p_idx); virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point); @@ -117,6 +118,7 @@ public: void set_spatial_node(Spatial *p_node); Spatial *get_spatial_node() const { return spatial_node; } + EditorSpatialGizmoPlugin *get_plugin() const { return gizmo_plugin; } Vector3 get_handle_pos(int p_idx) const; bool intersect_frustum(const Camera *p_camera, const Vector<Plane> &p_frustum); bool intersect_ray(Camera *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle = NULL, bool p_sec_first = false); @@ -786,7 +788,7 @@ public: virtual Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const; virtual void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point); virtual void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false); - virtual bool is_gizmo_handle_highlighted(const EditorSpatialGizmo *p_gizmo, int p_idx) const; + virtual bool is_handle_highlighted(const EditorSpatialGizmo *p_gizmo, int p_idx) const; Ref<EditorSpatialGizmo> get_gizmo(Spatial *p_spatial); void set_state(int p_state); diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp index 9f3a0e78f6..f62391e436 100644 --- a/editor/spatial_editor_gizmos.cpp +++ b/editor/spatial_editor_gizmos.cpp @@ -99,26 +99,63 @@ void EditorSpatialGizmo::clear() { void EditorSpatialGizmo::redraw() { + if (get_script_instance() && get_script_instance()->has_method("redraw")) { + get_script_instance()->call("redraw"); + return; + } + ERR_FAIL_COND(!gizmo_plugin); gizmo_plugin->redraw(this); } String EditorSpatialGizmo::get_handle_name(int p_idx) const { + + if (get_script_instance() && get_script_instance()->has_method("get_handle_name")) { + return get_script_instance()->call("get_handle_name", p_idx); + } + ERR_FAIL_COND_V(!gizmo_plugin, ""); return gizmo_plugin->get_handle_name(this, p_idx); } +bool EditorSpatialGizmo::is_handle_highlighted(int p_idx) const { + + if (get_script_instance() && get_script_instance()->has_method("is_handle_highlighted")) { + return get_script_instance()->call("is_handle_highlighted", p_idx); + } + + ERR_FAIL_COND_V(!gizmo_plugin, false); + return gizmo_plugin->is_handle_highlighted(this, p_idx); +} + Variant EditorSpatialGizmo::get_handle_value(int p_idx) { + + if (get_script_instance() && get_script_instance()->has_method("get_handle_value")) { + return get_script_instance()->call("get_handle_value", p_idx); + } + ERR_FAIL_COND_V(!gizmo_plugin, Variant()); return gizmo_plugin->get_handle_value(this, p_idx); } void EditorSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) { + + if (get_script_instance() && get_script_instance()->has_method("set_handle")) { + get_script_instance()->call("set_handle", p_idx, p_camera, p_point); + return; + } + ERR_FAIL_COND(!gizmo_plugin); return gizmo_plugin->set_handle(this, p_idx, p_camera, p_point); } void EditorSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) { + + if (get_script_instance() && get_script_instance()->has_method("commit_handle")) { + get_script_instance()->call("commit_handle", p_idx, p_restore, p_cancel); + return; + } + ERR_FAIL_COND(!gizmo_plugin); return gizmo_plugin->commit_handle(this, p_idx, p_restore, p_cancel); } @@ -298,7 +335,7 @@ void EditorSpatialGizmo::add_handles(const Vector<Vector3> &p_handles, const Ref for (int i = 0; i < p_handles.size(); i++) { Color col(1, 1, 1, 1); - if (gizmo_plugin->is_gizmo_handle_highlighted(this, i)) + if (is_handle_highlighted(i)) col = Color(0, 0, 1, 0.9); if (SpatialEditor::get_singleton()->get_over_gizmo_handle() != i) @@ -690,11 +727,14 @@ void EditorSpatialGizmo::_bind_methods() { ClassDB::bind_method(D_METHOD("add_unscaled_billboard", "material", "default_scale"), &EditorSpatialGizmo::add_unscaled_billboard, DEFVAL(1)); ClassDB::bind_method(D_METHOD("add_handles", "handles", "material", "billboard", "secondary"), &EditorSpatialGizmo::add_handles, DEFVAL(false), DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_spatial_node", "node"), &EditorSpatialGizmo::_set_spatial_node); + ClassDB::bind_method(D_METHOD("get_spatial_node"), &EditorSpatialGizmo::get_spatial_node); + ClassDB::bind_method(D_METHOD("get_plugin"), &EditorSpatialGizmo::get_plugin); ClassDB::bind_method(D_METHOD("clear"), &EditorSpatialGizmo::clear); ClassDB::bind_method(D_METHOD("set_hidden", "hidden"), &EditorSpatialGizmo::set_hidden); BIND_VMETHOD(MethodInfo("redraw")); BIND_VMETHOD(MethodInfo(Variant::STRING, "get_handle_name", PropertyInfo(Variant::INT, "index"))); + BIND_VMETHOD(MethodInfo(Variant::BOOL, "is_handle_highlighted", PropertyInfo(Variant::INT, "index"))); MethodInfo hvget(Variant::NIL, "get_handle_value", PropertyInfo(Variant::INT, "index")); hvget.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; @@ -2117,7 +2157,7 @@ void SoftBodySpatialGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int soft_body->pin_point_toggle(p_idx); } -bool SoftBodySpatialGizmoPlugin::is_gizmo_handle_highlighted(const EditorSpatialGizmo *p_gizmo, int idx) const { +bool SoftBodySpatialGizmoPlugin::is_handle_highlighted(const EditorSpatialGizmo *p_gizmo, int idx) const { SoftBody *soft_body = Object::cast_to<SoftBody>(p_gizmo->get_spatial_node()); return soft_body->is_point_pinned(idx); } diff --git a/editor/spatial_editor_gizmos.h b/editor/spatial_editor_gizmos.h index 40e137cded..0d89fb0f03 100644 --- a/editor/spatial_editor_gizmos.h +++ b/editor/spatial_editor_gizmos.h @@ -214,7 +214,7 @@ public: String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const; Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const; void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel); - bool is_gizmo_handle_highlighted(const EditorSpatialGizmo *p_gizmo, int idx) const; + bool is_handle_highlighted(const EditorSpatialGizmo *p_gizmo, int idx) const; SoftBodySpatialGizmoPlugin(); }; diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp index 09177205b4..22f2214898 100644 --- a/modules/bullet/rigid_body_bullet.cpp +++ b/modules/bullet/rigid_body_bullet.cpp @@ -797,6 +797,9 @@ void RigidBodyBullet::set_transform__bullet(const btTransform &p_global_transfor btBody->setLinearVelocity((p_global_transform.getOrigin() - btBody->getWorldTransform().getOrigin()) / space->get_delta_time()); // The kinematic use MotionState class godotMotionState->moveBody(p_global_transform); + } else { + // Is necesasry to avoid wrong location on the rendering side on the next frame + godotMotionState->setWorldTransform(p_global_transform); } CollisionObjectBullet::set_transform__bullet(p_global_transform); } @@ -822,7 +825,8 @@ void RigidBodyBullet::reload_shapes() { // shapes incorrectly do not set the vector in calculateLocalIntertia. // Arbitrary zero is preferable to undefined behaviour. btVector3 inertia(0, 0, 0); - mainShape->calculateLocalInertia(mass, inertia); + if (EMPTY_SHAPE_PROXYTYPE != mainShape->getShapeType()) // Necessary to avoid assertion of the empty shape + mainShape->calculateLocalInertia(mass, inertia); btBody->setMassProps(mass, inertia); } btBody->updateInertiaTensor(); diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index a13f731c11..f62e6f5c40 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -575,6 +575,18 @@ void CSGShape::_validate_property(PropertyInfo &property) const { } } +Array CSGShape::get_meshes() const { + + if (root_mesh.is_valid()) { + Array arr; + arr.resize(2); + arr[0] = Transform(); + arr[1] = root_mesh; + return arr; + } + + return Array(); +} void CSGShape::_bind_methods() { ClassDB::bind_method(D_METHOD("_update_shape"), &CSGShape::_update_shape); @@ -604,6 +616,8 @@ void CSGShape::_bind_methods() { ClassDB::bind_method(D_METHOD("set_calculate_tangents", "enabled"), &CSGShape::set_calculate_tangents); ClassDB::bind_method(D_METHOD("is_calculating_tangents"), &CSGShape::is_calculating_tangents); + ClassDB::bind_method(D_METHOD("get_meshes"), &CSGShape::get_meshes); + ADD_PROPERTY(PropertyInfo(Variant::INT, "operation", PROPERTY_HINT_ENUM, "Union,Intersection,Subtraction"), "set_operation", "get_operation"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "snap", PROPERTY_HINT_RANGE, "0.0001,1,0.001"), "set_snap", "get_snap"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "calculate_tangents"), "set_calculate_tangents", "is_calculating_tangents"); diff --git a/modules/csg/csg_shape.h b/modules/csg/csg_shape.h index df503faf2e..1622fb3a15 100644 --- a/modules/csg/csg_shape.h +++ b/modules/csg/csg_shape.h @@ -116,6 +116,8 @@ protected: virtual void _validate_property(PropertyInfo &property) const; + Array get_meshes() const; + public: void set_operation(Operation p_operation); Operation get_operation() const; diff --git a/modules/hdr/image_loader_hdr.cpp b/modules/hdr/image_loader_hdr.cpp index eb424d36f8..f75a4a926a 100644 --- a/modules/hdr/image_loader_hdr.cpp +++ b/modules/hdr/image_loader_hdr.cpp @@ -33,8 +33,6 @@ #include "core/os/os.h" #include "core/print_string.h" -#include "thirdparty/tinyexr/tinyexr.h" - Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) { String header = f->get_token(); diff --git a/modules/mono/utils/path_utils.cpp b/modules/mono/utils/path_utils.cpp index 80f2324e15..6e431f51e7 100644 --- a/modules/mono/utils/path_utils.cpp +++ b/modules/mono/utils/path_utils.cpp @@ -59,7 +59,7 @@ String path_which(const String &p_name) { #ifdef WINDOWS_ENABLED for (int j = 0; j < exts.size(); j++) { - String p2 = p + exts[j]; + String p2 = p + exts[j].to_lower(); // lowercase to reduce risk of case mismatch warning if (FileAccess::exists(p2)) return p2; diff --git a/modules/pvr/texture_loader_pvr.cpp b/modules/pvr/texture_loader_pvr.cpp index d3f2f3c272..01e011e64c 100644 --- a/modules/pvr/texture_loader_pvr.cpp +++ b/modules/pvr/texture_loader_pvr.cpp @@ -33,6 +33,7 @@ #include "RgbaBitmap.h" #include "core/os/file_access.h" #include <string.h> +#include <new> static void _pvrtc_decompress(Image *p_img); @@ -215,12 +216,10 @@ static void _compress_pvrtc4(Image *p_img) { int ofs, size, w, h; img->get_mipmap_offset_size_and_dimensions(i, ofs, size, w, h); Javelin::RgbaBitmap bm(w, h); - copymem(bm.GetData(), &r[ofs], size); - { + for (unsigned j = 0; j < size / 4; j++) { Javelin::ColorRgba<unsigned char> *dp = bm.GetData(); - for (int j = 0; j < size / 4; j++) { - SWAP(dp[j].r, dp[j].b); - } + /* red and Green colors are swapped. */ + new (dp) Javelin::ColorRgba<unsigned char>(r[ofs + 4 * j + 2], r[ofs + 4 * j + 1], r[ofs + 4 * j], r[ofs + 4 * j + 3]); } new_img->get_mipmap_offset_size_and_dimensions(i, ofs, size, w, h); diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp index 404ca24482..e36844a1bc 100644 --- a/modules/svg/image_loader_svg.cpp +++ b/modules/svg/image_loader_svg.cpp @@ -109,7 +109,12 @@ Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const PoolVector<uint8_t float upscale = upsample ? 2.0 : 1.0; int w = (int)(svg_image->width * p_scale * upscale); + ERR_EXPLAIN(vformat("Can't create image from SVG with scale %s, the resulting image size exceeds max width.", rtos(p_scale))); + ERR_FAIL_COND_V(w > Image::MAX_WIDTH, ERR_PARAMETER_RANGE_ERROR); + int h = (int)(svg_image->height * p_scale * upscale); + ERR_EXPLAIN(vformat("Can't create image from SVG with scale %s, the resulting image size exceeds max height.", rtos(p_scale))); + ERR_FAIL_COND_V(h > Image::MAX_HEIGHT, ERR_PARAMETER_RANGE_ERROR); PoolVector<uint8_t> dst_image; dst_image.resize(w * h * 4); diff --git a/modules/websocket/doc_classes/WebSocketClient.xml b/modules/websocket/doc_classes/WebSocketClient.xml index 6b73b80350..ffb6d40e30 100644 --- a/modules/websocket/doc_classes/WebSocketClient.xml +++ b/modules/websocket/doc_classes/WebSocketClient.xml @@ -25,7 +25,8 @@ </argument> <description> Connect to the given URL requesting one of the given [code]protocols[/code] as sub-protocol. - If [code]true[/code], is passed as [code]gd_mp_api[/code], the client will behave like a network peer for the [MultiplayerAPI]. Note: connections to non Godot servers will not work, and [signal data_received] will not be emitted when this option is true. + If [code]true[/code] is passed as [code]gd_mp_api[/code], the client will behave like a network peer for the [MultiplayerAPI], connections to non Godot servers will not work, and [signal data_received] will not be emitted. + If [code]false[/code] is passed instead (default), you must call [PacketPeer] functions ([code]put_packet[/code], [code]get_packet[/code], etc.) on the [WebSocketPeer] returned via [code]get_peer(1)[/code] and not on this object directly (e.g. [code]get_peer(1).put_packet(data)[/code]). </description> </method> <method name="disconnect_from_host"> diff --git a/modules/websocket/doc_classes/WebSocketServer.xml b/modules/websocket/doc_classes/WebSocketServer.xml index ba66fdd89b..2932bf782a 100644 --- a/modules/websocket/doc_classes/WebSocketServer.xml +++ b/modules/websocket/doc_classes/WebSocketServer.xml @@ -72,7 +72,8 @@ <description> Start listening on the given port. You can specify the desired subprotocols via the "protocols" array. If the list empty (default), "binary" will be used. - You can use this server as a network peer for [MultiplayerAPI] by passing [code]true[/code] as [code]gd_mp_api[/code]. Note: [signal data_received] will not be fired and clients other than Godot will not work in this case. + If [code]true[/code] is passed as [code]gd_mp_api[/code], the server will behave like a network peer for the [MultiplayerAPI], connections from non Godot clients will not work, and [signal data_received] will not be emitted. + If [code]false[/code] is passed instead (default), you must call [PacketPeer] functions ([code]put_packet[/code], [code]get_packet[/code], etc.), on the [WebSocketPeer] returned via [code]get_peer(ID)[/code] to communicate with the peer with given [code]ID[/code] (e.g. [code]get_peer(ID).get_available_packet_count[/code]). </description> </method> <method name="stop"> diff --git a/modules/websocket/websocket_multiplayer.cpp b/modules/websocket/websocket_multiplayer.cpp index 7c8cc36fad..11caac944b 100644 --- a/modules/websocket/websocket_multiplayer.cpp +++ b/modules/websocket/websocket_multiplayer.cpp @@ -96,6 +96,7 @@ void WebSocketMultiplayerPeer::_bind_methods() { // int WebSocketMultiplayerPeer::get_available_packet_count() const { + ERR_EXPLAIN("Please use get_peer(ID).get_available_packet_count to get available packet count from peers when not using the MultiplayerAPI."); ERR_FAIL_COND_V(!_is_multiplayer, ERR_UNCONFIGURED); return _incoming_packets.size(); @@ -103,9 +104,11 @@ int WebSocketMultiplayerPeer::get_available_packet_count() const { Error WebSocketMultiplayerPeer::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { - r_buffer_size = 0; + ERR_EXPLAIN("Please use get_peer(ID).get_packet/var to communicate with peers when not using the MultiplayerAPI."); ERR_FAIL_COND_V(!_is_multiplayer, ERR_UNCONFIGURED); + r_buffer_size = 0; + if (_current_packet.data != NULL) { memfree(_current_packet.data); _current_packet.data = NULL; @@ -122,6 +125,7 @@ Error WebSocketMultiplayerPeer::get_packet(const uint8_t **r_buffer, int &r_buff Error WebSocketMultiplayerPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) { + ERR_EXPLAIN("Please use get_peer(ID).put_packet/var to communicate with peers when not using the MultiplayerAPI."); ERR_FAIL_COND_V(!_is_multiplayer, ERR_UNCONFIGURED); PoolVector<uint8_t> buffer = _make_pkt(SYS_NONE, get_unique_id(), _target_peer, p_buffer, p_buffer_size); @@ -154,6 +158,7 @@ void WebSocketMultiplayerPeer::set_target_peer(int p_target_peer) { int WebSocketMultiplayerPeer::get_packet_peer() const { + ERR_EXPLAIN("This function is not available when not using the MultiplayerAPI."); ERR_FAIL_COND_V(!_is_multiplayer, 1); ERR_FAIL_COND_V(_incoming_packets.size() == 0, 1); diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index d7ba454051..e820d07a2a 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -442,6 +442,9 @@ void OS_JavaScript::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_s if (texture.is_valid()) { image = texture->get_data(); + if (image.is_valid()) { + image->duplicate(); + } } if (!image.is_valid() && atlas_texture.is_valid()) { @@ -468,6 +471,8 @@ void OS_JavaScript::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_s ERR_FAIL_COND(!image.is_valid()); + image = image->duplicate(); + if (atlas_texture.is_valid()) image->crop_from_point( atlas_rect.position.x, diff --git a/platform/osx/detect.py b/platform/osx/detect.py index 31fcbc0427..36a753e683 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -126,7 +126,7 @@ def configure(env): env.Append(CPPPATH=['#platform/osx']) env.Append(CPPFLAGS=['-DOSX_ENABLED', '-DUNIX_ENABLED', '-DGLES_ENABLED', '-DAPPLE_STYLE_KEYS', '-DCOREAUDIO_ENABLED', '-DCOREMIDI_ENABLED']) - env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'OpenGL', '-framework', 'AGL', '-framework', 'AudioUnit', '-framework', 'CoreAudio', '-framework', 'CoreMIDI', '-lz', '-framework', 'IOKit', '-framework', 'ForceFeedback']) + env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'OpenGL', '-framework', 'AGL', '-framework', 'AudioUnit', '-framework', 'CoreAudio', '-framework', 'CoreMIDI', '-lz', '-framework', 'IOKit', '-framework', 'ForceFeedback', '-framework', 'CoreVideo']) env.Append(LIBS=['pthread']) env.Append(CPPFLAGS=['-mmacosx-version-min=10.9']) diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index 262079fa89..927c8c9b00 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -43,8 +43,10 @@ #include "servers/visual/rasterizer.h" #include "servers/visual/visual_server_wrap_mt.h" #include "servers/visual_server.h" +#include <AppKit/AppKit.h> #include <AppKit/NSCursor.h> #include <ApplicationServices/ApplicationServices.h> +#include <CoreVideo/CoreVideo.h> #undef CursorShape /** @@ -102,10 +104,13 @@ public: id window_view; id autoreleasePool; id cursor; - id pixelFormat; - id context; + NSOpenGLPixelFormat *pixelFormat; + NSOpenGLContext *context; bool layered_window; + bool waiting_for_vsync; + NSCondition *vsync_condition; + CVDisplayLinkRef displayLink; CursorShape cursor_shape; NSCursor *cursors[CURSOR_MAX]; diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 760858b2e5..3f80d19fa1 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -117,6 +117,21 @@ static Vector2 get_mouse_pos(NSPoint locationInWindow, CGFloat backingScaleFacto return Vector2(mouse_x, mouse_y); } +// DisplayLinkCallback is called from our DisplayLink OS thread informing us right before +// a screen update is required. We can use it to work around the broken vsync. +static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp *now, const CVTimeStamp *outputTime, CVOptionFlags flagsIn, CVOptionFlags *flagsOut, void *displayLinkContext) { + OS_OSX *os = (OS_OSX *)displayLinkContext; + + // Set flag so we know we can output our next frame and signal our conditional lock + // if we're not doing vsync this will be ignored + [os->vsync_condition lock]; + os->waiting_for_vsync = false; + [os->vsync_condition signal]; + [os->vsync_condition unlock]; + + return kCVReturnSuccess; +} + @interface GodotApplication : NSApplication @end @@ -1366,6 +1381,15 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a [context makeCurrentContext]; + // setup our display link, this will inform us when a refresh is needed + CVDisplayLinkCreateWithActiveCGDisplays(&displayLink); + CVDisplayLinkSetOutputCallback(displayLink, &DisplayLinkCallback, this); + CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, context.CGLContextObj, pixelFormat.CGLPixelFormatObj); + CVDisplayLinkStart(displayLink); + + // initialise a conditional lock object + vsync_condition = [[NSCondition alloc] init]; + set_use_vsync(p_desired.use_vsync); [NSApp activateIgnoringOtherApps:YES]; @@ -1453,6 +1477,11 @@ void OS_OSX::finalize() { midi_driver.close(); #endif + if (displayLink) { + CVDisplayLinkRelease(displayLink); + } + [vsync_condition release]; + CFNotificationCenterRemoveObserver(CFNotificationCenterGetDistributedCenter(), NULL, kTISNotifySelectedKeyboardInputSourceChanged, NULL); CGDisplayRemoveReconfigurationCallback(displays_arrangement_changed, NULL); @@ -1967,6 +1996,17 @@ String OS_OSX::get_locale() const { } void OS_OSX::swap_buffers() { + if (is_vsync_enabled()) { + // Wait until our DisplayLink callback unsets our flag... + [vsync_condition lock]; + while (waiting_for_vsync) + [vsync_condition wait]; + + // Make sure we wait again next frame around + waiting_for_vsync = true; + + [vsync_condition unlock]; + } [context flushBuffer]; } @@ -2633,22 +2673,22 @@ Error OS_OSX::move_to_trash(const String &p_path) { } void OS_OSX::_set_use_vsync(bool p_enable) { - CGLContextObj ctx = CGLGetCurrentContext(); + // CGLCPSwapInterval broke in OSX 10.14 and it seems Apple is not interested in fixing + // it as OpenGL is now deprecated and Metal solves this differently. + // Following SDLs example we're working around this using DisplayLink + // When vsync is enabled we set a flag "waiting_for_vsync" to true. + // This flag is set to false when DisplayLink informs us our display is about to refresh. + + /* CGLContextObj ctx = CGLGetCurrentContext(); if (ctx) { GLint swapInterval = p_enable ? 1 : 0; CGLSetParameter(ctx, kCGLCPSwapInterval, &swapInterval); - } -} -/* -bool OS_OSX::is_vsync_enabled() const { - GLint swapInterval = 0; - CGLContextObj ctx = CGLGetCurrentContext(); - if (ctx) { - CGLGetParameter(ctx, kCGLCPSwapInterval, &swapInterval); - } - return swapInterval ? true : false; + }*/ + + ///TODO Maybe pause/unpause display link? + waiting_for_vsync = p_enable; } -*/ + OS_OSX *OS_OSX::singleton = NULL; OS_OSX::OS_OSX() { diff --git a/platform/windows/joypad.cpp b/platform/windows/joypad.cpp index ba05d2e495..5fafc7c8c0 100644 --- a/platform/windows/joypad.cpp +++ b/platform/windows/joypad.cpp @@ -29,9 +29,9 @@ /*************************************************************************/ #include "joypad.h" + #include <oleauto.h> #include <wbemidl.h> -#include <iostream> #ifndef __GNUC__ #define __builtin_bswap32 _byteswap_ulong @@ -149,15 +149,12 @@ bool JoypadWindows::setup_dinput_joypad(const DIDEVICEINSTANCE *instance) { const DWORD devtype = (instance->dwDevType & 0xFF); if ((devtype != DI8DEVTYPE_JOYSTICK) && (devtype != DI8DEVTYPE_GAMEPAD) && (devtype != DI8DEVTYPE_1STPERSON)) { - //printf("ignore device %s, type %x\n", instance->tszProductName, devtype); return false; } hr = dinput->CreateDevice(instance->guidInstance, &joy->di_joy, NULL); if (FAILED(hr)) { - - //std::wcout << "failed to create device: " << instance->tszProductName << std::endl; return false; } @@ -383,8 +380,6 @@ void JoypadWindows::process_joypads() { hr = joy->di_joy->GetDeviceState(sizeof(DIJOYSTATE2), &js); if (FAILED(hr)) { - - //printf("failed to read joy #%d\n", i); continue; } diff --git a/platform/x11/SCsub b/platform/x11/SCsub index 97d3d1b514..e302f09c88 100644 --- a/platform/x11/SCsub +++ b/platform/x11/SCsub @@ -13,6 +13,7 @@ common_x11 = [ "key_mapping_x11.cpp", "joypad_linux.cpp", "power_x11.cpp", + "detect_prime.cpp" ] prog = env.add_program('#bin/godot', ['godot_x11.cpp'] + common_x11) diff --git a/platform/x11/detect_prime.cpp b/platform/x11/detect_prime.cpp new file mode 100644 index 0000000000..04a825fac9 --- /dev/null +++ b/platform/x11/detect_prime.cpp @@ -0,0 +1,233 @@ +/*************************************************************************/ +/* detect_prime.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifdef X11_ENABLED +#if defined(OPENGL_ENABLED) + +#include "core/print_string.h" +#include "core/ustring.h" + +#include <stdlib.h> + +#include <GL/gl.h> +#include <GL/glx.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +#include <cstring> + +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> + +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 + +typedef GLXContext (*GLXCREATECONTEXTATTRIBSARBPROC)(Display *, GLXFBConfig, GLXContext, Bool, const int *); + +struct vendor { + const char *glxvendor; + int priority; +}; + +vendor vendormap[] = { + { "Advanced Micro Devices, Inc.", 30 }, + { "NVIDIA Corporation", 30 }, + { "X.Org", 30 }, + { "Intel Open Source Technology Center", 20 }, + { "nouveau", 10 }, + { "Mesa Project", 0 }, + { NULL, 0 } +}; + +// Runs inside a child. Exiting will not quit the engine. +void create_context() { + Display *x11_display = XOpenDisplay(NULL); + Window x11_window; + GLXContext glx_context; + + GLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (GLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((const GLubyte *)"glXCreateContextAttribsARB"); + + static int visual_attribs[] = { + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, + GLX_DOUBLEBUFFER, true, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + GLX_DEPTH_SIZE, 24, + None + }; + + int fbcount; + GLXFBConfig fbconfig = 0; + XVisualInfo *vi = NULL; + + XSetWindowAttributes swa; + swa.event_mask = StructureNotifyMask; + swa.border_pixel = 0; + unsigned long valuemask = CWBorderPixel | CWColormap | CWEventMask; + + GLXFBConfig *fbc = glXChooseFBConfig(x11_display, DefaultScreen(x11_display), visual_attribs, &fbcount); + if (!fbc) + exit(1); + + vi = glXGetVisualFromFBConfig(x11_display, fbc[0]); + + fbconfig = fbc[0]; + + static int context_attribs[] = { + GLX_CONTEXT_MAJOR_VERSION_ARB, 3, + GLX_CONTEXT_MINOR_VERSION_ARB, 3, + GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, + GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, + None + }; + + glx_context = glXCreateContextAttribsARB(x11_display, fbconfig, NULL, true, context_attribs); + + 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, 10, 10, 0, vi->depth, InputOutput, vi->visual, valuemask, &swa); + + if (!x11_window) + exit(1); + + glXMakeCurrent(x11_display, x11_window, glx_context); + XFree(vi); +} + +int detect_prime() { + pid_t p; + int priorities[2]; + String vendors[2]; + String renderers[2]; + + vendors[0] = "Unknown"; + vendors[1] = "Unknown"; + renderers[0] = "Unknown"; + renderers[1] = "Unknown"; + + for (int i = 0; i < 2; ++i) { + int fdset[2]; + + if (pipe(fdset) == -1) { + print_verbose("Failed to pipe(), using default GPU"); + return 0; + } + + // Fork so the driver initialization can crash without taking down the engine. + p = fork(); + + if (p > 0) { + // Main thread + + int stat_loc = 0; + char string[201]; + string[200] = '\0'; + + close(fdset[1]); + + waitpid(p, &stat_loc, 0); + + if (!stat_loc) { + // No need to do anything complicated here. Anything less than + // PIPE_BUF will be delivered in one read() call. + read(fdset[0], string, sizeof(string) - 1); + + vendors[i] = string; + renderers[i] = string + strlen(string) + 1; + } + + close(fdset[0]); + + } else { + // In child, exit() here will not quit the engine. + + char string[201]; + + close(fdset[0]); + + if (i) setenv("DRI_PRIME", "1", 1); + create_context(); + + const char *vendor = (const char *)glGetString(GL_VENDOR); + const char *renderer = (const char *)glGetString(GL_RENDERER); + + int vendor_len = strlen(vendor) + 1; + int renderer_len = strlen(renderer) + 1; + + if (vendor_len + renderer_len >= sizeof(string)) { + renderer_len = 200 - vendor_len; + } + + memcpy(&string, vendor, vendor_len); + memcpy(&string[vendor_len], renderer, renderer_len); + + write(fdset[1], string, vendor_len + renderer_len); + + close(fdset[1]); + exit(0); + } + } + + int preferred = 0; + int priority = 0; + + if (vendors[0] == vendors[1]) { + print_verbose("Only one GPU found, using default."); + return 0; + } + + for (int i = 1; i >= 0; --i) { + vendor *v = vendormap; + while (v->glxvendor) { + if (v->glxvendor == vendors[i]) { + priorities[i] = v->priority; + + if (v->priority >= priority) { + priority = v->priority; + preferred = i; + } + } + ++v; + } + } + + print_verbose("Found renderers:"); + for (int i = 0; i < 2; ++i) { + print_verbose("Renderer " + itos(i) + ": " + renderers[i] + " with priority: " + itos(priorities[i])); + } + + print_verbose("Using renderer: " + renderers[preferred]); + return preferred; +} + +#endif +#endif diff --git a/platform/x11/detect_prime.h b/platform/x11/detect_prime.h new file mode 100644 index 0000000000..13bcf6fc38 --- /dev/null +++ b/platform/x11/detect_prime.h @@ -0,0 +1,37 @@ +/*************************************************************************/ +/* detect_prime.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifdef X11_ENABLED +#if defined(OPENGL_ENABLED) + +int detect_prime(); + +#endif +#endif diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 0db79fa3e9..e0924fc982 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -29,6 +29,8 @@ /*************************************************************************/ #include "os_x11.h" +#include "detect_prime.h" + #include "core/os/dir_access.h" #include "core/print_string.h" #include "drivers/gles2/rasterizer_gles2.h" @@ -240,28 +242,15 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a // maybe contextgl wants to be in charge of creating the window #if defined(OPENGL_ENABLED) - // Set DRI_PRIME if not set. This means that Godot should default to a higher-power GPU if it exists. - // Note: Due to the final '0' parameter to setenv any existing DRI_PRIME environment variables will not - // be overwritten. - bool enable_dri_prime = true; - // Check if Nouveau is loaded, we don't want to force dGPU usage with that driver. - if (FileAccess *f = FileAccess::open("/proc/modules", FileAccess::READ)) { - // Match driver name + space - String nouveau_str = "nouveau "; - - while (!f->eof_reached()) { - String line = f->get_line(); - - if (line.begins_with(nouveau_str)) { - enable_dri_prime = false; - break; - } + if (getenv("DRI_PRIME") == NULL) { + print_verbose("Detecting GPUs, set DRI_PRIME in the environment to override GPU detection logic."); + int use_prime = detect_prime(); + + if (use_prime) { + print_line("Found discrete GPU, setting DRI_PRIME=1 to use it."); + print_line("Note: Set DRI_PRIME=0 in the environment to disable Godot from using the discrete GPU."); + setenv("DRI_PRIME", "1", 1); } - f->close(); - memdelete(f); - } - if (enable_dri_prime) { - setenv("DRI_PRIME", "1", 0); } ContextGL_X11::ContextType opengl_api_type = ContextGL_X11::GLES_3_0_COMPATIBLE; diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp index 707e95e271..28ddf6b5f8 100644 --- a/scene/2d/animated_sprite.cpp +++ b/scene/2d/animated_sprite.cpp @@ -395,8 +395,8 @@ void AnimatedSprite::_notification(int p_what) { int fc = frames->get_frame_count(animation); if (frame >= fc - 1) { if (frames->get_animation_loop(animation)) { - emit_signal(SceneStringNames::get_singleton()->animation_finished); frame = 0; + emit_signal(SceneStringNames::get_singleton()->animation_finished); } else { frame = fc - 1; if (!is_over) { diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index d7ed6f8f49..d1fce74085 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -431,7 +431,7 @@ void Light2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "is_editor_only"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "StreamTexture,ImageTexture"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_texture_offset", "get_texture_offset"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "texture_scale", PROPERTY_HINT_RANGE, "0.01,50,0.01"), "set_texture_scale", "get_texture_scale"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index fd28b876f3..ed9374e422 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -495,6 +495,7 @@ void Camera::_bind_methods() { ClassDB::bind_method(D_METHOD("get_keep_aspect_mode"), &Camera::get_keep_aspect_mode); ClassDB::bind_method(D_METHOD("set_doppler_tracking", "mode"), &Camera::set_doppler_tracking); ClassDB::bind_method(D_METHOD("get_doppler_tracking"), &Camera::get_doppler_tracking); + ClassDB::bind_method(D_METHOD("get_frustum"), &Camera::get_frustum); ClassDB::bind_method(D_METHOD("set_cull_mask_bit", "layer", "enable"), &Camera::set_cull_mask_bit); ClassDB::bind_method(D_METHOD("get_cull_mask_bit", "layer"), &Camera::get_cull_mask_bit); diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index 56faba27cf..08cc655cdd 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -373,7 +373,7 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *sm, if (fading_from != StringName()) { - sm->blend_node(current, sm->states[fading_from].node, p_time, p_seek, 1.0 - fade_blend, AnimationNode::FILTER_IGNORE, false); + sm->blend_node(fading_from, sm->states[fading_from].node, p_time, p_seek, 1.0 - fade_blend, AnimationNode::FILTER_IGNORE, false); } //guess playback position diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 6ed465562e..4b1c7b3db7 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -35,6 +35,7 @@ #include "core/os/os.h" #ifdef TOOLS_ENABLED +#include "editor_scale.h" #include "editor_settings.h" #endif @@ -81,11 +82,8 @@ void ColorPicker::_notification(int p_what) { } break; case MainLoop::NOTIFICATION_WM_QUIT_REQUEST: { - if (screen != NULL) { - if (screen->is_visible()) { - screen->hide(); - } - } + if (screen != NULL && screen->is_visible()) + screen->hide(); } break; } } @@ -156,7 +154,7 @@ void ColorPicker::_value_changed(double) { void ColorPicker::_html_entered(const String &p_html) { - if (updating) + if (updating || text_is_constructor || !c_text->is_visible()) return; float last_alpha = color.a; @@ -211,15 +209,18 @@ void ColorPicker::_update_presets() { } void ColorPicker::_text_type_toggled() { - if (!Engine::get_singleton()->is_editor_hint()) - return; + text_is_constructor = !text_is_constructor; if (text_is_constructor) { text_type->set_text(""); text_type->set_icon(get_icon("Script", "EditorIcons")); + + c_text->set_editable(false); } else { text_type->set_text("#"); text_type->set_icon(NULL); + + c_text->set_editable(true); } _update_color(); } @@ -304,19 +305,21 @@ bool ColorPicker::is_deferred_mode() const { void ColorPicker::_update_text_value() { bool visible = true; if (text_is_constructor) { - String t = "Color(" + String::num(color.r) + "," + String::num(color.g) + "," + String::num(color.b); + String t = "Color(" + String::num(color.r) + ", " + String::num(color.g) + ", " + String::num(color.b); if (edit_alpha && color.a < 1) - t += ("," + String::num(color.a) + ")"); + t += ", " + String::num(color.a) + ")"; else t += ")"; c_text->set_text(t); - } else { - if (color.r > 1 || color.g > 1 || color.b > 1 || color.r < 0 || color.g < 0 || color.b < 0) { - visible = false; - } else { - c_text->set_text(color.to_html(edit_alpha && color.a < 1)); - } } + + if (color.r > 1 || color.g > 1 || color.b > 1 || color.r < 0 || color.g < 0 || color.b < 0) { + visible = false; + } else if (!text_is_constructor) { + c_text->set_text(color.to_html(edit_alpha && color.a < 1)); + } + + text_type->set_visible(visible); c_text->set_visible(visible); } @@ -494,21 +497,17 @@ void ColorPicker::_preset_input(const Ref<InputEvent> &p_event) { void ColorPicker::_screen_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> bev = p_event; - - if (bev.is_valid()) { - - if (bev->get_button_index() == BUTTON_LEFT && !bev->is_pressed()) { - emit_signal("color_changed", color); - screen->hide(); - } + if (bev.is_valid() && bev->get_button_index() == BUTTON_LEFT && !bev->is_pressed()) { + emit_signal("color_changed", color); + screen->hide(); } Ref<InputEventMouseMotion> mev = p_event; - if (mev.is_valid()) { Viewport *r = get_tree()->get_root(); if (!r->get_visible_rect().has_point(Point2(mev->get_global_position().x, mev->get_global_position().y))) return; + Ref<Image> img = r->get_texture()->get_data(); if (img.is_valid() && !img->empty()) { img->lock(); @@ -534,6 +533,8 @@ void ColorPicker::_screen_pick_pressed() { screen->set_anchors_and_margins_preset(Control::PRESET_WIDE); screen->set_default_cursor_shape(CURSOR_POINTING_HAND); screen->connect("gui_input", this, "_screen_input"); + // It immediately toggles off in the first press otherwise. + screen->call_deferred("connect", "hide", btn_pick, "set_pressed", varray(false)); } screen->raise(); screen->show_modal(); @@ -615,22 +616,25 @@ ColorPicker::ColorPicker() : screen = NULL; HBoxContainer *hb_smpl = memnew(HBoxContainer); - btn_pick = memnew(ToolButton); - btn_pick->connect("pressed", this, "_screen_pick_pressed"); + add_child(hb_smpl); sample = memnew(TextureRect); + hb_smpl->add_child(sample); sample->set_h_size_flags(SIZE_EXPAND_FILL); sample->connect("draw", this, "_sample_draw"); - hb_smpl->add_child(sample); + btn_pick = memnew(ToolButton); hb_smpl->add_child(btn_pick); - add_child(hb_smpl); + btn_pick->set_toggle_mode(true); + btn_pick->set_tooltip(TTR("Pick a color from the screen.")); + btn_pick->connect("pressed", this, "_screen_pick_pressed"); HBoxContainer *hb_edit = memnew(HBoxContainer); + add_child(hb_edit); hb_edit->set_v_size_flags(SIZE_EXPAND_FILL); uv_edit = memnew(Control); - + hb_edit->add_child(uv_edit); uv_edit->connect("gui_input", this, "_uv_input"); uv_edit->set_mouse_filter(MOUSE_FILTER_PASS); uv_edit->set_h_size_flags(SIZE_EXPAND_FILL); @@ -638,19 +642,14 @@ ColorPicker::ColorPicker() : uv_edit->set_custom_minimum_size(Size2(get_constant("sv_width"), get_constant("sv_height"))); uv_edit->connect("draw", this, "_hsv_draw", make_binds(0, uv_edit)); - add_child(hb_edit); - w_edit = memnew(Control); + hb_edit->add_child(w_edit); w_edit->set_custom_minimum_size(Size2(get_constant("h_width"), 0)); w_edit->set_h_size_flags(SIZE_FILL); w_edit->set_v_size_flags(SIZE_EXPAND_FILL); w_edit->connect("gui_input", this, "_w_input"); w_edit->connect("draw", this, "_hsv_draw", make_binds(1, w_edit)); - hb_edit->add_child(uv_edit); - hb_edit->add_child(memnew(VSeparator)); - hb_edit->add_child(w_edit); - VBoxContainer *vbl = memnew(VBoxContainer); add_child(vbl); @@ -691,31 +690,43 @@ ColorPicker::ColorPicker() : } HBoxContainer *hhb = memnew(HBoxContainer); + vbr->add_child(hhb); btn_mode = memnew(CheckButton); + hhb->add_child(btn_mode); btn_mode->set_text(TTR("Raw Mode")); btn_mode->connect("toggled", this, "set_raw_mode"); - hhb->add_child(btn_mode); - vbr->add_child(hhb); + text_type = memnew(Button); - text_type->set_flat(true); - text_type->connect("pressed", this, "_text_type_toggled"); hhb->add_child(text_type); + text_type->set_text("#"); + text_type->set_tooltip(TTR("Switch between hexadecimal and code values.")); + if (Engine::get_singleton()->is_editor_hint()) { + +#ifdef TOOLS_ENABLED + text_type->set_custom_minimum_size(Size2(28 * EDSCALE, 0)); // Adjust for the width of the "Script" icon. +#endif + text_type->connect("pressed", this, "_text_type_toggled"); + } else { + + text_type->set_flat(true); + text_type->set_mouse_filter(MOUSE_FILTER_IGNORE); + } c_text = memnew(LineEdit); hhb->add_child(c_text); + c_text->set_h_size_flags(SIZE_EXPAND_FILL); c_text->connect("text_entered", this, "_html_entered"); c_text->connect("focus_entered", this, "_focus_enter"); c_text->connect("focus_exited", this, "_html_focus_exit"); - text_type->set_text("#"); - c_text->set_h_size_flags(SIZE_EXPAND_FILL); - _update_controls(); updating = false; set_pick_color(Color(1, 1, 1)); + add_child(memnew(HSeparator)); + HBoxContainer *bbc = memnew(HBoxContainer); add_child(bbc); @@ -725,9 +736,9 @@ ColorPicker::ColorPicker() : preset->connect("draw", this, "_update_presets"); bt_add_preset = memnew(Button); + bbc->add_child(bt_add_preset); bt_add_preset->set_tooltip(TTR("Add current color as a preset")); bt_add_preset->connect("pressed", this, "_add_preset_pressed"); - bbc->add_child(bt_add_preset); } ///////////////// @@ -838,9 +849,9 @@ void ColorPickerButton::_bind_methods() { ColorPickerButton::ColorPickerButton() { - //Initialization is now done deferred - //this improves performance in the inspector as the color picker - //can be expensive to initialize + // Initialization is now done deferred, + // this improves performance in the inspector as the color picker + // can be expensive to initialize. picker = NULL; popup = NULL; edit_alpha = true; diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index 7ecf9a2b16..c72ccc97db 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -497,6 +497,7 @@ Size2 Font::get_string_size(const String &p_string) const { } void BitmapFont::set_fallback(const Ref<BitmapFont> &p_fallback) { + ERR_FAIL_COND(p_fallback == this); fallback = p_fallback; } diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index dcad70451e..ff5900cd3e 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -943,6 +943,7 @@ uint32_t AtlasTexture::get_flags() const { void AtlasTexture::set_atlas(const Ref<Texture> &p_atlas) { + ERR_FAIL_COND(p_atlas == this); if (atlas == p_atlas) return; atlas = p_atlas; @@ -1182,6 +1183,7 @@ void LargeTexture::set_piece_offset(int p_idx, const Point2 &p_offset) { void LargeTexture::set_piece_texture(int p_idx, const Ref<Texture> &p_texture) { + ERR_FAIL_COND(p_texture == this); ERR_FAIL_INDEX(p_idx, pieces.size()); pieces.write[p_idx].texture = p_texture; }; @@ -1747,6 +1749,7 @@ void ProxyTexture::_bind_methods() { void ProxyTexture::set_base(const Ref<Texture> &p_texture) { + ERR_FAIL_COND(p_texture == this); base = p_texture; if (base.is_valid()) { VS::get_singleton()->texture_set_proxy(proxy, base->get_rid()); @@ -1862,6 +1865,8 @@ int AnimatedTexture::get_frames() const { } void AnimatedTexture::set_frame_texture(int p_frame, const Ref<Texture> &p_texture) { + + ERR_FAIL_COND(p_texture == this); ERR_FAIL_INDEX(p_frame, MAX_FRAMES); RWLockWrite w(rw_lock); diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 931ee98e47..d96b37938f 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -1046,32 +1046,40 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "point_size", "POINT_SIZE" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "world", "WORLD_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "modelview", "MODELVIEW_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "camera", "CAMERA_MATRIX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_camera", "INV_CAMERA_MATRIX" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_projection", "INV_PROJECTION_MATRIX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "vp_size", "vec3(VIEWPORT_SIZE, 0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(VIEWPORT_SIZE, 0)" }, // Spatial, Fragment + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.xyz" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "vertex", "VERTEX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "NORMAL" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "tangent", "TANGENT" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "binormal", "BINORMAL" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "view", "VIEW" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv2", "vec3(UV2,0.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec2(POINT_COORD,0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec3(POINT_COORD,0.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV,0.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "side", "float(FRONT_FACING ? 1.0 : 0.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "world", "WORLD_MATRIX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_camera", "INV_CAMERA_MATRIX" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "camera", "CAMERA_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_projection", "INV_PROJECTION_MATRIX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "vp_size", "vec3(VIEWPORT_SIZE, 0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(VIEWPORT_SIZE, 0.0)" }, // Spatial, Light + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.xyz" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "NORMAL" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "view", "VIEW" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light", "LIGHT" }, @@ -1083,15 +1091,18 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "world", "WORLD_MATRIX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_camera", "INV_CAMERA_MATRIX" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "camera", "CAMERA_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_projection", "INV_PROJECTION_MATRIX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "vp_size", "vec3(VIEWPORT_SIZE, 0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(VIEWPORT_SIZE, 0.0)" }, // Canvas Item, Vertex { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "vertex", "vec3(VERTEX,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "point_size", "POINT_SIZE" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "texture_pixel_size", "vec3(TEXTURE_PIXEL_SIZE, 1.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "world", "WORLD_MATRIX" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION_MATRIX" }, @@ -1099,14 +1110,18 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "light_pass", "float(AT_LIGHT_PASS ? 1.0 : 0.0)" }, // Canvas Item, Fragment + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.xyz" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV,0.0)" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec2(POINT_COORD,0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "texture_pixel_size", "vec3(TEXTURE_PIXEL_SIZE, 1.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_pixel_size", "vec3(SCREEN_PIXEL_SIZE, 1.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec3(POINT_COORD,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "light_pass", "float(AT_LIGHT_PASS ? 1.0 : 0.0)" }, // Canvas Item, Light + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.xyz" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "NORMAL" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, @@ -1117,10 +1132,11 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_alpha", "LIGHT_COLOR.a" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_uv", "vec3(LIGHT_UV,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "shadow_color", "SHADOW_COLOR.rgb" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV,0.0)" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec2(POINT_COORD,0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "texture_pixel_size", "vec3(TEXTURE_PIXEL_SIZE, 1.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec3(POINT_COORD,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, + // Particles, Vertex { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, @@ -1151,16 +1167,16 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::preview_ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "1.0" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(UV,0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV,0.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "side", "1.0" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "vp_size", "vec3(1.0,1.0, 0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(1.0,1.0, 0.0)" }, // Spatial, Light { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "vec3(0.0,0.0,1.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "vp_size", "vec3(1.0, 1.0, 0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(1.0, 1.0, 0.0)" }, // Canvas Item, Vertex { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "vertex", "vec3(VERTEX,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, @@ -1171,7 +1187,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::preview_ports[] = { { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "1.0" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(UV,0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, // Canvas Item, Light { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, @@ -1179,7 +1195,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::preview_ports[] = { { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "1.0" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(UV,0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, // Particles, Vertex { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" }, diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index 0c43000186..4e167be300 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -81,7 +81,6 @@ static void _debugger_get_resource_usage(List<ScriptDebuggerRemote::ResourceUsag ShaderTypes *shader_types = NULL; PhysicsServer *_createGodotPhysicsCallback() { - WARN_PRINT("The GodotPhysics 3D physics engine is deprecated and will be removed in Godot 3.2. You should use the Bullet physics engine instead (configurable in your project settings)."); return memnew(PhysicsServerSW); } @@ -167,8 +166,8 @@ void register_server_types() { GLOBAL_DEF(PhysicsServerManager::setting_property_name, "DEFAULT"); ProjectSettings::get_singleton()->set_custom_property_info(PhysicsServerManager::setting_property_name, PropertyInfo(Variant::STRING, PhysicsServerManager::setting_property_name, PROPERTY_HINT_ENUM, "DEFAULT")); - PhysicsServerManager::register_server("GodotPhysics - deprecated", &_createGodotPhysicsCallback); - PhysicsServerManager::set_default_server("GodotPhysics - deprecated"); + PhysicsServerManager::register_server("GodotPhysics", &_createGodotPhysicsCallback); + PhysicsServerManager::set_default_server("GodotPhysics"); } void unregister_server_types() { diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 6f8a30070a..33081dcd0c 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -221,6 +221,7 @@ public: virtual void textures_keep_original(bool p_enable) = 0; virtual void texture_set_proxy(RID p_proxy, RID p_base) = 0; + virtual Size2 texture_size_with_proxy(RID p_texture) const = 0; virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) = 0; /* SKY API */ diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index d2046241f0..c8d64fca45 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -32,6 +32,7 @@ #include "core/os/os.h" #include "visual_server_global.h" #include "visual_server_raster.h" +#include <new> /* CAMERA API */ RID VisualServerScene::camera_create() { @@ -1253,7 +1254,9 @@ void VisualServerScene::_update_instance_lightmap_captures(Instance *p_instance) //print_line("update captures for pos: " + p_instance->transform.origin); - zeromem(p_instance->lightmap_capture_data.ptrw(), 12 * sizeof(Color)); + for (int i = 0; i < 12; i++) + new (&p_instance->lightmap_capture_data.ptrw()[i]) Color; + //this could use some sort of blending.. for (List<Instance *>::Element *E = geom->lightmap_captures.front(); E; E = E->next()) { const PoolVector<RasterizerStorage::LightmapCaptureOctree> *octree = VSG::storage->lightmap_capture_get_octree_ptr(E->get()->base); diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp index 92b17eae47..7a7ae3a823 100644 --- a/servers/visual/visual_server_viewport.cpp +++ b/servers/visual/visual_server_viewport.cpp @@ -97,7 +97,7 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E RasterizerCanvas::Light *cl = F->get(); if (cl->enabled && cl->texture.is_valid()) { //not super efficient.. - Size2 tsize(VSG::storage->texture_get_width(cl->texture), VSG::storage->texture_get_height(cl->texture)); + Size2 tsize = VSG::storage->texture_size_with_proxy(cl->texture); tsize *= cl->scale; Vector2 offset = tsize / 2.0; |