summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--COPYRIGHT.txt2
-rw-r--r--SConstruct2
-rw-r--r--core/SCsub1
-rw-r--r--core/input/SCsub1
-rw-r--r--doc/classes/BaseButton.xml4
-rw-r--r--doc/classes/PopupMenu.xml32
-rw-r--r--doc/classes/Shortcut.xml (renamed from doc/classes/ShortCut.xml)2
-rw-r--r--doc/classes/Tabs.xml7
-rw-r--r--doc/classes/Texture3D.xml49
-rw-r--r--doc/classes/VisualShaderNodeTexture.xml2
-rw-r--r--doc/classes/VisualShaderNodeTexture3D.xml20
-rw-r--r--doc/classes/VisualShaderNodeTexture3DUniform.xml15
-rw-r--r--editor/editor_node.cpp8
-rw-r--r--editor/editor_settings.cpp30
-rw-r--r--editor/editor_settings.h10
-rw-r--r--editor/icons/Shortcut.svg (renamed from editor/icons/ShortCut.svg)0
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h10
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp2
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp5
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp7
-rw-r--r--editor/settings_config_dialog.cpp6
-rwxr-xr-xeditor/translations/extract.py2
-rw-r--r--glsl_builders.py5
-rw-r--r--main/main_builders.py1
-rw-r--r--misc/dist/html/fixed-size.html1
-rw-r--r--modules/bullet/shape_bullet.cpp2
-rw-r--r--modules/denoise/resource_to_cpp.py2
-rw-r--r--modules/mono/build_scripts/mono_configure.py1
-rw-r--r--modules/tinyexr/image_loader_tinyexr.cpp158
-rw-r--r--platform/osx/detect.py1
-rw-r--r--scene/gui/base_button.cpp6
-rw-r--r--scene/gui/base_button.h6
-rw-r--r--scene/gui/color_picker.cpp4
-rw-r--r--scene/gui/popup_menu.cpp24
-rw-r--r--scene/gui/popup_menu.h24
-rw-r--r--scene/gui/shortcut.cpp24
-rw-r--r--scene/gui/shortcut.h6
-rw-r--r--scene/gui/tabs.cpp9
-rw-r--r--scene/gui/tabs.h2
-rw-r--r--scene/main/scene_tree.h6
-rw-r--r--scene/register_scene_types.cpp5
-rw-r--r--scene/resources/visual_shader_nodes.cpp126
-rw-r--r--scene/resources/visual_shader_nodes.h46
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp3
-rw-r--r--thirdparty/README.md2
-rw-r--r--thirdparty/tinyexr/tinyexr.cc6
-rw-r--r--thirdparty/tinyexr/tinyexr.h710
48 files changed, 969 insertions, 431 deletions
diff --git a/.gitignore b/.gitignore
index 6af581040c..8d1aad947d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -383,3 +383,6 @@ ruby.png
snow.png
updown.png
gcov.css
+
+# https://clangd.llvm.org/ cache folder
+.clangd/
diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt
index 8ccdecd307..757913f0bd 100644
--- a/COPYRIGHT.txt
+++ b/COPYRIGHT.txt
@@ -338,7 +338,7 @@ License: Expat
Files: ./thirdparty/tinyexr/
Comment: TinyEXR
-Copyright: 2014-2019, Syoyo Fujita
+Copyright: 2014-2020, Syoyo Fujita
2002, Industrial Light & Magic, a division of Lucas Digital Ltd. LLC
License: BSD-3-clause
diff --git a/SConstruct b/SConstruct
index 64a4c48eff..b7b0321039 100644
--- a/SConstruct
+++ b/SConstruct
@@ -13,8 +13,6 @@ from collections import OrderedDict
# Local
import methods
import glsl_builders
-import version
-from platform_methods import run_in_subprocess
# Scan possible build platforms
diff --git a/core/SCsub b/core/SCsub
index 40ee78d3ea..16ee49d003 100644
--- a/core/SCsub
+++ b/core/SCsub
@@ -4,7 +4,6 @@ Import("env")
import core_builders
import make_binders
-from platform_methods import run_in_subprocess
env.core_sources = []
diff --git a/core/input/SCsub b/core/input/SCsub
index f40978911b..740398b266 100644
--- a/core/input/SCsub
+++ b/core/input/SCsub
@@ -2,7 +2,6 @@
Import("env")
-from platform_methods import run_in_subprocess
import input_builders
diff --git a/doc/classes/BaseButton.xml b/doc/classes/BaseButton.xml
index 3812b45b13..bf4d9383ac 100644
--- a/doc/classes/BaseButton.xml
+++ b/doc/classes/BaseButton.xml
@@ -65,8 +65,8 @@
<member name="pressed" type="bool" setter="set_pressed" getter="is_pressed" default="false">
If [code]true[/code], the button's state is pressed. Means the button is pressed down or toggled (if [member toggle_mode] is active).
</member>
- <member name="shortcut" type="ShortCut" setter="set_shortcut" getter="get_shortcut">
- [ShortCut] associated to the button.
+ <member name="shortcut" type="Shortcut" setter="set_shortcut" getter="get_shortcut">
+ [Shortcut] associated to the button.
</member>
<member name="shortcut_in_tooltip" type="bool" setter="set_shortcut_in_tooltip" getter="is_shortcut_in_tooltip_enabled" default="true">
If [code]true[/code], the button will add information about its shortcut in the tooltip.
diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml
index 2af0f500a0..b1ec9a222a 100644
--- a/doc/classes/PopupMenu.xml
+++ b/doc/classes/PopupMenu.xml
@@ -29,14 +29,14 @@
<method name="add_check_shortcut">
<return type="void">
</return>
- <argument index="0" name="shortcut" type="ShortCut">
+ <argument index="0" name="shortcut" type="Shortcut">
</argument>
<argument index="1" name="id" type="int" default="-1">
</argument>
<argument index="2" name="global" type="bool" default="false">
</argument>
<description>
- Adds a new checkable item and assigns the specified [ShortCut] to it. Sets the label of the checkbox to the [ShortCut]'s name.
+ Adds a new checkable item and assigns the specified [Shortcut] to it. Sets the label of the checkbox to the [Shortcut]'s name.
An [code]id[/code] can optionally be provided. If no [code]id[/code] is provided, one will be created from the index.
[b]Note:[/b] Checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually. See [method set_item_checked] for more info on how to control it.
</description>
@@ -63,14 +63,14 @@
</return>
<argument index="0" name="texture" type="Texture2D">
</argument>
- <argument index="1" name="shortcut" type="ShortCut">
+ <argument index="1" name="shortcut" type="Shortcut">
</argument>
<argument index="2" name="id" type="int" default="-1">
</argument>
<argument index="3" name="global" type="bool" default="false">
</argument>
<description>
- Adds a new checkable item and assigns the specified [ShortCut] and icon [code]texture[/code] to it. Sets the label of the checkbox to the [ShortCut]'s name.
+ Adds a new checkable item and assigns the specified [Shortcut] and icon [code]texture[/code] to it. Sets the label of the checkbox to the [Shortcut]'s name.
An [code]id[/code] can optionally be provided. If no [code]id[/code] is provided, one will be created from the index.
[b]Note:[/b] Checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually. See [method set_item_checked] for more info on how to control it.
</description>
@@ -111,7 +111,7 @@
</return>
<argument index="0" name="texture" type="Texture2D">
</argument>
- <argument index="1" name="shortcut" type="ShortCut">
+ <argument index="1" name="shortcut" type="Shortcut">
</argument>
<argument index="2" name="id" type="int" default="-1">
</argument>
@@ -126,14 +126,14 @@
</return>
<argument index="0" name="texture" type="Texture2D">
</argument>
- <argument index="1" name="shortcut" type="ShortCut">
+ <argument index="1" name="shortcut" type="Shortcut">
</argument>
<argument index="2" name="id" type="int" default="-1">
</argument>
<argument index="3" name="global" type="bool" default="false">
</argument>
<description>
- Adds a new item and assigns the specified [ShortCut] and icon [code]texture[/code] to it. Sets the label of the checkbox to the [ShortCut]'s name.
+ Adds a new item and assigns the specified [Shortcut] and icon [code]texture[/code] to it. Sets the label of the checkbox to the [Shortcut]'s name.
An [code]id[/code] can optionally be provided. If no [code]id[/code] is provided, one will be created from the index.
</description>
</method>
@@ -188,14 +188,14 @@
<method name="add_radio_check_shortcut">
<return type="void">
</return>
- <argument index="0" name="shortcut" type="ShortCut">
+ <argument index="0" name="shortcut" type="Shortcut">
</argument>
<argument index="1" name="id" type="int" default="-1">
</argument>
<argument index="2" name="global" type="bool" default="false">
</argument>
<description>
- Adds a new radio check button and assigns a [ShortCut] to it. Sets the label of the checkbox to the [ShortCut]'s name.
+ Adds a new radio check button and assigns a [Shortcut] to it. Sets the label of the checkbox to the [Shortcut]'s name.
An [code]id[/code] can optionally be provided. If no [code]id[/code] is provided, one will be created from the index.
[b]Note:[/b] Checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually. See [method set_item_checked] for more info on how to control it.
</description>
@@ -212,14 +212,14 @@
<method name="add_shortcut">
<return type="void">
</return>
- <argument index="0" name="shortcut" type="ShortCut">
+ <argument index="0" name="shortcut" type="Shortcut">
</argument>
<argument index="1" name="id" type="int" default="-1">
</argument>
<argument index="2" name="global" type="bool" default="false">
</argument>
<description>
- Adds a [ShortCut].
+ Adds a [Shortcut].
An [code]id[/code] can optionally be provided. If no [code]id[/code] is provided, one will be created from the index.
</description>
</method>
@@ -303,12 +303,12 @@
</description>
</method>
<method name="get_item_shortcut" qualifiers="const">
- <return type="ShortCut">
+ <return type="Shortcut">
</return>
<argument index="0" name="idx" type="int">
</argument>
<description>
- Returns the [ShortCut] associated with the specified [code]idx[/code] item.
+ Returns the [Shortcut] associated with the specified [code]idx[/code] item.
</description>
</method>
<method name="get_item_submenu" qualifiers="const">
@@ -521,12 +521,12 @@
</return>
<argument index="0" name="idx" type="int">
</argument>
- <argument index="1" name="shortcut" type="ShortCut">
+ <argument index="1" name="shortcut" type="Shortcut">
</argument>
<argument index="2" name="global" type="bool" default="false">
</argument>
<description>
- Sets a [ShortCut] for the specified item [code]idx[/code].
+ Sets a [Shortcut] for the specified item [code]idx[/code].
</description>
</method>
<method name="set_item_shortcut_disabled">
@@ -537,7 +537,7 @@
<argument index="1" name="disabled" type="bool">
</argument>
<description>
- Disables the [ShortCut] of the specified index [code]idx[/code].
+ Disables the [Shortcut] of the specified index [code]idx[/code].
</description>
</method>
<method name="set_item_submenu">
diff --git a/doc/classes/ShortCut.xml b/doc/classes/Shortcut.xml
index 9a2a761969..55bbb083c9 100644
--- a/doc/classes/ShortCut.xml
+++ b/doc/classes/Shortcut.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="ShortCut" inherits="Resource" version="4.0">
+<class name="Shortcut" inherits="Resource" version="4.0">
<brief_description>
A shortcut for binding input.
</brief_description>
diff --git a/doc/classes/Tabs.xml b/doc/classes/Tabs.xml
index 3fc1db9dc6..ef1f370185 100644
--- a/doc/classes/Tabs.xml
+++ b/doc/classes/Tabs.xml
@@ -36,6 +36,13 @@
Returns [code]true[/code] if the offset buttons (the ones that appear when there's not enough space for all tabs) are visible.
</description>
</method>
+ <method name="get_previous_tab" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the previously active tab index.
+ </description>
+ </method>
<method name="get_select_with_rmb" qualifiers="const">
<return type="bool">
</return>
diff --git a/doc/classes/Texture3D.xml b/doc/classes/Texture3D.xml
new file mode 100644
index 0000000000..85e940716d
--- /dev/null
+++ b/doc/classes/Texture3D.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="Texture3D" inherits="Texture" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="get_data" qualifiers="const">
+ <return type="Image[]">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_depth" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_format" qualifiers="const">
+ <return type="int" enum="Image.Format">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_height" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_width" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="has_mipmaps" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/VisualShaderNodeTexture.xml b/doc/classes/VisualShaderNodeTexture.xml
index 8e389e0b40..0c83ffffe4 100644
--- a/doc/classes/VisualShaderNodeTexture.xml
+++ b/doc/classes/VisualShaderNodeTexture.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeTexture" inherits="VisualShaderNode" version="4.0">
<brief_description>
- Performs a texture lookup within the visual shader graph.
+ Performs a 2D texture lookup within the visual shader graph.
</brief_description>
<description>
Performs a lookup operation on the provided texture, with support for multiple texture sources to choose from.
diff --git a/doc/classes/VisualShaderNodeTexture3D.xml b/doc/classes/VisualShaderNodeTexture3D.xml
new file mode 100644
index 0000000000..17929e823e
--- /dev/null
+++ b/doc/classes/VisualShaderNodeTexture3D.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeTexture3D" inherits="VisualShaderNodeSample3D" version="4.0">
+ <brief_description>
+ Performs a 3D texture lookup within the visual shader graph.
+ </brief_description>
+ <description>
+ Performs a lookup operation on the provided texture, with support for multiple texture sources to choose from.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="texture" type="Texture3D" setter="set_texture" getter="get_texture">
+ A source texture. Used if [member VisualShaderNodeSample3D.source] is set to [constant VisualShaderNodeSample3D.SOURCE_TEXTURE].
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/VisualShaderNodeTexture3DUniform.xml b/doc/classes/VisualShaderNodeTexture3DUniform.xml
new file mode 100644
index 0000000000..d9e9acf117
--- /dev/null
+++ b/doc/classes/VisualShaderNodeTexture3DUniform.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeTexture3DUniform" inherits="VisualShaderNodeTextureUniform" version="4.0">
+ <brief_description>
+ Provides a 3D texture uniform within the visual shader graph.
+ </brief_description>
+ <description>
+ Translated to [code]uniform sampler3D[/code] in the shader language.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 6c830b8074..4835b4beab 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -2819,9 +2819,9 @@ void EditorNode::_discard_changes(const String &p_str) {
}
void EditorNode::_update_file_menu_opened() {
- Ref<ShortCut> close_scene_sc = ED_GET_SHORTCUT("editor/close_scene");
+ Ref<Shortcut> close_scene_sc = ED_GET_SHORTCUT("editor/close_scene");
close_scene_sc->set_name(TTR("Close Scene"));
- Ref<ShortCut> reopen_closed_scene_sc = ED_GET_SHORTCUT("editor/reopen_closed_scene");
+ Ref<Shortcut> reopen_closed_scene_sc = ED_GET_SHORTCUT("editor/reopen_closed_scene");
reopen_closed_scene_sc->set_name(TTR("Reopen Closed Scene"));
PopupMenu *pop = file_menu->get_popup();
pop->set_item_disabled(pop->get_item_index(FILE_OPEN_PREV), previous_scenes.empty());
@@ -4714,10 +4714,10 @@ void EditorNode::_scene_tab_input(const Ref<InputEvent> &p_input) {
scene_tabs_context_menu->add_item(TTR("Play This Scene"), RUN_PLAY_SCENE);
scene_tabs_context_menu->add_separator();
- Ref<ShortCut> close_tab_sc = ED_GET_SHORTCUT("editor/close_scene");
+ Ref<Shortcut> close_tab_sc = ED_GET_SHORTCUT("editor/close_scene");
close_tab_sc->set_name(TTR("Close Tab"));
scene_tabs_context_menu->add_shortcut(close_tab_sc, FILE_CLOSE);
- Ref<ShortCut> undo_close_tab_sc = ED_GET_SHORTCUT("editor/reopen_closed_scene");
+ Ref<Shortcut> undo_close_tab_sc = ED_GET_SHORTCUT("editor/reopen_closed_scene");
undo_close_tab_sc->set_name(TTR("Undo Close Tab"));
scene_tabs_context_menu->add_shortcut(undo_close_tab_sc, FILE_OPEN_PREV);
if (previous_scenes.empty()) {
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 0aefef7018..8be157ffb5 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -77,7 +77,7 @@ bool EditorSettings::_set_only(const StringName &p_name, const Variant &p_value)
String name = arr[i];
Ref<InputEvent> shortcut = arr[i + 1];
- Ref<ShortCut> sc;
+ Ref<Shortcut> sc;
sc.instance();
sc->set_shortcut(shortcut);
add_shortcut(name, sc);
@@ -120,8 +120,8 @@ bool EditorSettings::_get(const StringName &p_name, Variant &r_ret) const {
if (p_name.operator String() == "shortcuts") {
Array arr;
- for (const Map<String, Ref<ShortCut>>::Element *E = shortcuts.front(); E; E = E->next()) {
- Ref<ShortCut> sc = E->get();
+ for (const Map<String, Ref<Shortcut>>::Element *E = shortcuts.front(); E; E = E->next()) {
+ Ref<Shortcut> sc = E->get();
if (optimize_save) {
if (!sc->has_meta("original")) {
@@ -1481,50 +1481,50 @@ String EditorSettings::get_editor_layouts_config() const {
// Shortcuts
-void EditorSettings::add_shortcut(const String &p_name, Ref<ShortCut> &p_shortcut) {
+void EditorSettings::add_shortcut(const String &p_name, Ref<Shortcut> &p_shortcut) {
shortcuts[p_name] = p_shortcut;
}
bool EditorSettings::is_shortcut(const String &p_name, const Ref<InputEvent> &p_event) const {
- const Map<String, Ref<ShortCut>>::Element *E = shortcuts.find(p_name);
+ const Map<String, Ref<Shortcut>>::Element *E = shortcuts.find(p_name);
ERR_FAIL_COND_V_MSG(!E, false, "Unknown Shortcut: " + p_name + ".");
return E->get()->is_shortcut(p_event);
}
-Ref<ShortCut> EditorSettings::get_shortcut(const String &p_name) const {
- const Map<String, Ref<ShortCut>>::Element *E = shortcuts.find(p_name);
+Ref<Shortcut> EditorSettings::get_shortcut(const String &p_name) const {
+ const Map<String, Ref<Shortcut>>::Element *E = shortcuts.find(p_name);
if (!E) {
- return Ref<ShortCut>();
+ return Ref<Shortcut>();
}
return E->get();
}
void EditorSettings::get_shortcut_list(List<String> *r_shortcuts) {
- for (const Map<String, Ref<ShortCut>>::Element *E = shortcuts.front(); E; E = E->next()) {
+ for (const Map<String, Ref<Shortcut>>::Element *E = shortcuts.front(); E; E = E->next()) {
r_shortcuts->push_back(E->key());
}
}
-Ref<ShortCut> ED_GET_SHORTCUT(const String &p_path) {
+Ref<Shortcut> ED_GET_SHORTCUT(const String &p_path) {
if (!EditorSettings::get_singleton()) {
return nullptr;
}
- Ref<ShortCut> sc = EditorSettings::get_singleton()->get_shortcut(p_path);
+ Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(p_path);
ERR_FAIL_COND_V_MSG(!sc.is_valid(), sc, "Used ED_GET_SHORTCUT with invalid shortcut: " + p_path + ".");
return sc;
}
-struct ShortCutMapping {
+struct ShortcutMapping {
const char *path;
uint32_t keycode;
};
-Ref<ShortCut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p_keycode) {
+Ref<Shortcut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p_keycode) {
#ifdef OSX_ENABLED
// Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS
if (p_keycode == KEY_DELETE) {
@@ -1545,7 +1545,7 @@ Ref<ShortCut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p
}
if (!EditorSettings::get_singleton()) {
- Ref<ShortCut> sc;
+ Ref<Shortcut> sc;
sc.instance();
sc->set_name(p_name);
sc->set_shortcut(ie);
@@ -1553,7 +1553,7 @@ Ref<ShortCut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p
return sc;
}
- Ref<ShortCut> sc = EditorSettings::get_singleton()->get_shortcut(p_path);
+ Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(p_path);
if (sc.is_valid()) {
sc->set_name(p_name); //keep name (the ones that come from disk have no name)
sc->set_meta("original", ie); //to compare against changes
diff --git a/editor/editor_settings.h b/editor/editor_settings.h
index 13aebb7ea6..4896fb58db 100644
--- a/editor/editor_settings.h
+++ b/editor/editor_settings.h
@@ -85,7 +85,7 @@ private:
int last_order;
Ref<Resource> clipboard;
- Map<String, Ref<ShortCut>> shortcuts;
+ Map<String, Ref<Shortcut>> shortcuts;
String resource_path;
String settings_dir;
@@ -182,9 +182,9 @@ public:
Vector<String> get_script_templates(const String &p_extension, const String &p_custom_path = String());
String get_editor_layouts_config() const;
- void add_shortcut(const String &p_name, Ref<ShortCut> &p_shortcut);
+ void add_shortcut(const String &p_name, Ref<Shortcut> &p_shortcut);
bool is_shortcut(const String &p_name, const Ref<InputEvent> &p_event) const;
- Ref<ShortCut> get_shortcut(const String &p_name) const;
+ Ref<Shortcut> get_shortcut(const String &p_name) const;
void get_shortcut_list(List<String> *r_shortcuts);
void notify_changes();
@@ -203,7 +203,7 @@ Variant _EDITOR_DEF(const String &p_setting, const Variant &p_default, bool p_re
Variant _EDITOR_GET(const String &p_setting);
#define ED_IS_SHORTCUT(p_name, p_ev) (EditorSettings::get_singleton()->is_shortcut(p_name, p_ev))
-Ref<ShortCut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p_keycode = 0);
-Ref<ShortCut> ED_GET_SHORTCUT(const String &p_path);
+Ref<Shortcut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p_keycode = 0);
+Ref<Shortcut> ED_GET_SHORTCUT(const String &p_path);
#endif // EDITOR_SETTINGS_H
diff --git a/editor/icons/ShortCut.svg b/editor/icons/Shortcut.svg
index 4ef16f0401..4ef16f0401 100644
--- a/editor/icons/ShortCut.svg
+++ b/editor/icons/Shortcut.svg
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index ea58fb1e36..859e80befe 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -400,11 +400,11 @@ private:
Ref<Texture2D> select_handle;
Ref<Texture2D> anchor_handle;
- Ref<ShortCut> drag_pivot_shortcut;
- Ref<ShortCut> set_pivot_shortcut;
- Ref<ShortCut> multiply_grid_step_shortcut;
- Ref<ShortCut> divide_grid_step_shortcut;
- Ref<ShortCut> pan_view_shortcut;
+ Ref<Shortcut> drag_pivot_shortcut;
+ Ref<Shortcut> set_pivot_shortcut;
+ Ref<Shortcut> multiply_grid_step_shortcut;
+ Ref<Shortcut> divide_grid_step_shortcut;
+ Ref<Shortcut> pan_view_shortcut;
bool _is_node_locked(const Node *p_node);
bool _is_node_movable(const Node *p_node, bool p_popup_warning = false);
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 952487c13c..d28bbadf39 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -2246,7 +2246,7 @@ Point2i Node3DEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMouse
}
static bool is_shortcut_pressed(const String &p_path) {
- Ref<ShortCut> shortcut = ED_GET_SHORTCUT(p_path);
+ Ref<Shortcut> shortcut = ED_GET_SHORTCUT(p_path);
if (shortcut.is_null()) {
return false;
}
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index e71485e9fc..8cd8aaf277 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -802,7 +802,6 @@ void TileMapEditor::_draw_cell(Control *p_viewport, int p_cell, const Point2i &p
r.size = node->get_tileset()->autotile_get_size(p_cell);
r.position += (r.size + Vector2(spacing, spacing)) * offset;
}
- Size2 sc = p_xform.get_scale();
Size2 cell_size = node->get_cell_size();
bool centered_texture = node->is_centered_textures_enabled();
bool compatibility_mode_enabled = node->is_compatibility_mode_enabled();
@@ -838,12 +837,12 @@ void TileMapEditor::_draw_cell(Control *p_viewport, int p_cell, const Point2i &p
}
if (p_flip_h) {
- sc.x *= -1.0;
+ rect.size.x *= -1.0;
tile_ofs.x *= -1.0;
}
if (p_flip_v) {
- sc.y *= -1.0;
+ rect.size.y *= -1.0;
tile_ofs.y *= -1.0;
}
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index ccd236cbe4..734255ca55 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -2974,12 +2974,15 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("CubeMap", "Textures", "Functions", "VisualShaderNodeCubemap", TTR("Perform the cubic texture lookup."), -1, -1));
texture_node_option_idx = add_options.size();
- add_options.push_back(AddOption("Texture2D", "Textures", "Functions", "VisualShaderNodeTexture", TTR("Perform the texture lookup."), -1, -1));
- add_options.push_back(AddOption("CubeMapUniform", "Textures", "Variables", "VisualShaderNodeCubemapUniform", TTR("Cubic texture uniform lookup."), -1, -1));
+ add_options.push_back(AddOption("Texture2D", "Textures", "Functions", "VisualShaderNodeTexture", TTR("Perform the 2D texture lookup."), -1, -1));
add_options.push_back(AddOption("Texture2DArray", "Textures", "Functions", "VisualShaderNodeTexture2DArray", TTR("Perform the 2D-array texture lookup."), -1, -1, -1, -1, -1));
+ add_options.push_back(AddOption("Texture3D", "Textures", "Functions", "VisualShaderNodeTexture3D", TTR("Perform the 3D texture lookup."), -1, -1));
+
+ add_options.push_back(AddOption("CubeMapUniform", "Textures", "Variables", "VisualShaderNodeCubemapUniform", TTR("Cubic texture uniform lookup."), -1, -1));
add_options.push_back(AddOption("TextureUniform", "Textures", "Variables", "VisualShaderNodeTextureUniform", TTR("2D texture uniform lookup."), -1, -1));
add_options.push_back(AddOption("TextureUniformTriplanar", "Textures", "Variables", "VisualShaderNodeTextureUniformTriplanar", TTR("2D texture uniform lookup with triplanar."), -1, -1, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Texture2DArrayUniform", "Textures", "Variables", "VisualShaderNodeTexture2DArrayUniform", TTR("2D array of textures uniform lookup."), -1, -1, -1, -1, -1));
+ add_options.push_back(AddOption("Texture3DUniform", "Textures", "Variables", "VisualShaderNodeTexture3DUniform", TTR("3D texture uniform lookup."), -1, -1, -1, -1, -1));
// TRANSFORM
diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp
index 35610ef71b..5da682a148 100644
--- a/editor/settings_config_dialog.cpp
+++ b/editor/settings_config_dialog.cpp
@@ -202,7 +202,7 @@ void EditorSettingsDialog::_update_shortcuts() {
Map<String, TreeItem *> sections;
for (List<String>::Element *E = slist.front(); E; E = E->next()) {
- Ref<ShortCut> sc = EditorSettings::get_singleton()->get_shortcut(E->get());
+ Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(E->get());
if (!sc->has_meta("original")) {
continue;
}
@@ -268,7 +268,7 @@ void EditorSettingsDialog::_shortcut_button_pressed(Object *p_item, int p_column
ERR_FAIL_COND(!ti);
String item = ti->get_metadata(0);
- Ref<ShortCut> sc = EditorSettings::get_singleton()->get_shortcut(item);
+ Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(item);
if (p_idx == 0) {
press_a_key_label->set_text(TTR("Press a Key..."));
@@ -335,7 +335,7 @@ void EditorSettingsDialog::_press_a_key_confirm() {
ie->set_alt(last_wait_for_key->get_alt());
ie->set_metakey(last_wait_for_key->get_metakey());
- Ref<ShortCut> sc = EditorSettings::get_singleton()->get_shortcut(shortcut_configured);
+ Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(shortcut_configured);
undo_redo->create_action(TTR("Change Shortcut") + " '" + shortcut_configured + "'");
undo_redo->add_do_method(sc.ptr(), "set_shortcut", ie);
diff --git a/editor/translations/extract.py b/editor/translations/extract.py
index 0dafd20eed..93124ec30c 100755
--- a/editor/translations/extract.py
+++ b/editor/translations/extract.py
@@ -70,7 +70,6 @@ def _write_message(msgctx, msg, msg_plural, location):
def _add_additional_location(msgctx, msg, location):
global main_po
# Add additional location to previous occurrence.
- msg_pos = -1
if msgctx != "":
msg_pos = main_po.find('\nmsgctxt "' + msgctx + '"\nmsgid "' + msg + '"')
else:
@@ -86,7 +85,6 @@ def _write_translator_comment(msgctx, msg, translator_comment):
return
global main_po
- msg_pos = -1
if msgctx != "":
msg_pos = main_po.find('\nmsgctxt "' + msgctx + '"\nmsgid "' + msg + '"')
else:
diff --git a/glsl_builders.py b/glsl_builders.py
index af9afcae70..e1a6e41bea 100644
--- a/glsl_builders.py
+++ b/glsl_builders.py
@@ -211,11 +211,6 @@ def build_raw_header(filename):
fd.close()
-def build_rd_headers(target, source, env):
- for x in source:
- build_rd_header(str(x))
-
-
def build_raw_headers(target, source, env):
for x in source:
build_raw_header(str(x))
diff --git a/main/main_builders.py b/main/main_builders.py
index 2ea774e3b4..aa91201c3e 100644
--- a/main/main_builders.py
+++ b/main/main_builders.py
@@ -4,7 +4,6 @@ All such functions are invoked in a subprocess on Windows to prevent build flaki
"""
from platform_methods import subprocess_main
-from collections import OrderedDict
def make_splash(target, source, env):
diff --git a/misc/dist/html/fixed-size.html b/misc/dist/html/fixed-size.html
index a5633115d5..85064b34fd 100644
--- a/misc/dist/html/fixed-size.html
+++ b/misc/dist/html/fixed-size.html
@@ -236,7 +236,6 @@ $GODOT_HEAD_INCLUDE
const DEBUG_ENABLED = $GODOT_DEBUG_ENABLED;
const INDETERMINATE_STATUS_STEP_MS = 100;
- var container = document.getElementById('container');
var canvas = document.getElementById('canvas');
var statusProgress = document.getElementById('status-progress');
var statusProgressInner = document.getElementById('status-progress-inner');
diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp
index 274493ed17..74d6e073b3 100644
--- a/modules/bullet/shape_bullet.cpp
+++ b/modules/bullet/shape_bullet.cpp
@@ -308,7 +308,7 @@ void CapsuleShapeBullet::setup(real_t p_height, real_t p_radius) {
}
btCollisionShape *CapsuleShapeBullet::internal_create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) {
- return prepare(ShapeBullet::create_shape_capsule(radius * p_implicit_scale[0] + p_extra_edge, height * p_implicit_scale[1] + p_extra_edge));
+ return prepare(ShapeBullet::create_shape_capsule(radius * p_implicit_scale[0] + p_extra_edge, height * p_implicit_scale[1]));
}
/* Cylinder */
diff --git a/modules/denoise/resource_to_cpp.py b/modules/denoise/resource_to_cpp.py
index 4c0b67f701..6c83277355 100644
--- a/modules/denoise/resource_to_cpp.py
+++ b/modules/denoise/resource_to_cpp.py
@@ -17,8 +17,6 @@
## ======================================================================== ##
import os
-import sys
-import argparse
from array import array
# Generates a C++ file from the specified binary resource file
diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py
index 3e771e06f0..e959312393 100644
--- a/modules/mono/build_scripts/mono_configure.py
+++ b/modules/mono/build_scripts/mono_configure.py
@@ -1,6 +1,5 @@
import os
import os.path
-import sys
import subprocess
from SCons.Script import Dir, Environment
diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp
index 9e7266b95a..5bdcb84244 100644
--- a/modules/tinyexr/image_loader_tinyexr.cpp
+++ b/modules/tinyexr/image_loader_tinyexr.cpp
@@ -73,8 +73,10 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
}
// Read HALF channel as FLOAT. (GH-13490)
+ bool use_float16 = false;
for (int i = 0; i < exr_header.num_channels; i++) {
if (exr_header.pixel_types[i] == TINYEXR_PIXELTYPE_HALF) {
+ use_float16 = true;
exr_header.requested_pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT;
}
}
@@ -102,33 +104,10 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
idxB = c;
} else if (strcmp(exr_header.channels[c].name, "A") == 0) {
idxA = c;
- }
- }
-
- if (exr_header.num_channels == 1) {
- // Grayscale channel only.
- idxR = 0;
- idxG = 0;
- idxB = 0;
- idxA = 0;
- } else {
- // Assume RGB(A)
- if (idxR == -1) {
- ERR_PRINT("TinyEXR: R channel not found.");
- // @todo { free exr_image }
- return ERR_FILE_CORRUPT;
- }
-
- if (idxG == -1) {
- ERR_PRINT("TinyEXR: G channel not found.");
- // @todo { free exr_image }
- return ERR_FILE_CORRUPT;
- }
-
- if (idxB == -1) {
- ERR_PRINT("TinyEXR: B channel not found.");
- // @todo { free exr_image }
- return ERR_FILE_CORRUPT;
+ } else if (strcmp(exr_header.channels[c].name, "Y") == 0) {
+ idxR = c;
+ idxG = c;
+ idxB = c;
}
}
@@ -138,14 +117,27 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
Image::Format format;
int output_channels = 0;
+ int channel_size = use_float16 ? 2 : 4;
if (idxA != -1) {
- imgdata.resize(exr_image.width * exr_image.height * 8); //RGBA16
- format = Image::FORMAT_RGBAH;
+ imgdata.resize(exr_image.width * exr_image.height * 4 * channel_size); //RGBA
+ format = use_float16 ? Image::FORMAT_RGBAH : Image::FORMAT_RGBAF;
output_channels = 4;
- } else {
- imgdata.resize(exr_image.width * exr_image.height * 6); //RGB16
- format = Image::FORMAT_RGBH;
+ } else if (idxB != -1) {
+ ERR_FAIL_COND_V(idxG == -1, ERR_FILE_CORRUPT);
+ ERR_FAIL_COND_V(idxR == -1, ERR_FILE_CORRUPT);
+ imgdata.resize(exr_image.width * exr_image.height * 3 * channel_size); //RGB
+ format = use_float16 ? Image::FORMAT_RGBH : Image::FORMAT_RGBF;
output_channels = 3;
+ } else if (idxG != -1) {
+ ERR_FAIL_COND_V(idxR == -1, ERR_FILE_CORRUPT);
+ imgdata.resize(exr_image.width * exr_image.height * 2 * channel_size); //RG
+ format = use_float16 ? Image::FORMAT_RGH : Image::FORMAT_RGF;
+ output_channels = 2;
+ } else {
+ ERR_FAIL_COND_V(idxR == -1, ERR_FILE_CORRUPT);
+ imgdata.resize(exr_image.width * exr_image.height * 1 * channel_size); //R
+ format = use_float16 ? Image::FORMAT_RH : Image::FORMAT_RF;
+ output_channels = 1;
}
EXRTile single_image_tile;
@@ -175,9 +167,11 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
exr_tiles = exr_image.tiles;
}
+ //print_line("reading format: " + Image::get_format_name(format));
{
uint8_t *wd = imgdata.ptrw();
- uint16_t *iw = (uint16_t *)wd;
+ uint16_t *iw16 = (uint16_t *)wd;
+ float *iw32 = (float *)wd;
// Assume `out_rgba` have enough memory allocated.
for (int tile_index = 0; tile_index < num_tiles; tile_index++) {
@@ -187,41 +181,99 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
int th = tile.height;
const float *r_channel_start = reinterpret_cast<const float *>(tile.images[idxR]);
- const float *g_channel_start = reinterpret_cast<const float *>(tile.images[idxG]);
- const float *b_channel_start = reinterpret_cast<const float *>(tile.images[idxB]);
+ const float *g_channel_start = nullptr;
+ const float *b_channel_start = nullptr;
const float *a_channel_start = nullptr;
+ if (idxG != -1) {
+ g_channel_start = reinterpret_cast<const float *>(tile.images[idxG]);
+ }
+ if (idxB != -1) {
+ b_channel_start = reinterpret_cast<const float *>(tile.images[idxB]);
+ }
if (idxA != -1) {
a_channel_start = reinterpret_cast<const float *>(tile.images[idxA]);
}
- uint16_t *first_row_w = iw + (tile.offset_y * tile_height * exr_image.width + tile.offset_x * tile_width) * output_channels;
+ uint16_t *first_row_w16 = iw16 + (tile.offset_y * tile_height * exr_image.width + tile.offset_x * tile_width) * output_channels;
+ float *first_row_w32 = iw32 + (tile.offset_y * tile_height * exr_image.width + tile.offset_x * tile_width) * output_channels;
for (int y = 0; y < th; y++) {
const float *r_channel = r_channel_start + y * tile_width;
- const float *g_channel = g_channel_start + y * tile_width;
- const float *b_channel = b_channel_start + y * tile_width;
+ const float *g_channel = nullptr;
+ const float *b_channel = nullptr;
const float *a_channel = nullptr;
-
+ if (g_channel_start) {
+ g_channel = g_channel_start + y * tile_width;
+ }
+ if (b_channel_start) {
+ b_channel = b_channel_start + y * tile_width;
+ }
if (a_channel_start) {
a_channel = a_channel_start + y * tile_width;
}
- uint16_t *row_w = first_row_w + (y * exr_image.width * output_channels);
-
- for (int x = 0; x < tw; x++) {
- Color color(*r_channel++, *g_channel++, *b_channel++);
-
- if (p_force_linear) {
- color = color.to_linear();
+ if (use_float16) {
+ uint16_t *row_w = first_row_w16 + (y * exr_image.width * output_channels);
+
+ for (int x = 0; x < tw; x++) {
+ Color color;
+ color.r = *r_channel++;
+ if (g_channel) {
+ color.g = *g_channel++;
+ }
+ if (b_channel) {
+ color.b = *b_channel++;
+ }
+ if (a_channel) {
+ color.a = *a_channel++;
+ }
+
+ if (p_force_linear) {
+ color = color.to_linear();
+ }
+
+ *row_w++ = Math::make_half_float(color.r);
+ if (g_channel) {
+ *row_w++ = Math::make_half_float(color.g);
+ }
+ if (b_channel) {
+ *row_w++ = Math::make_half_float(color.b);
+ }
+ if (a_channel) {
+ *row_w++ = Math::make_half_float(color.a);
+ }
}
-
- *row_w++ = Math::make_half_float(color.r);
- *row_w++ = Math::make_half_float(color.g);
- *row_w++ = Math::make_half_float(color.b);
-
- if (idxA != -1) {
- *row_w++ = Math::make_half_float(*a_channel++);
+ } else {
+ float *row_w = first_row_w32 + (y * exr_image.width * output_channels);
+
+ for (int x = 0; x < tw; x++) {
+ Color color;
+ color.r = *r_channel++;
+ if (g_channel) {
+ color.g = *g_channel++;
+ }
+ if (b_channel) {
+ color.b = *b_channel++;
+ }
+ if (a_channel) {
+ color.a = *a_channel++;
+ }
+
+ if (p_force_linear) {
+ color = color.to_linear();
+ }
+
+ *row_w++ = color.r;
+ if (g_channel) {
+ *row_w++ = color.g;
+ }
+ if (b_channel) {
+ *row_w++ = color.b;
+ }
+ if (a_channel) {
+ *row_w++ = color.a;
+ }
}
}
}
diff --git a/platform/osx/detect.py b/platform/osx/detect.py
index a4a382f3a9..6fc1dc65af 100644
--- a/platform/osx/detect.py
+++ b/platform/osx/detect.py
@@ -1,6 +1,5 @@
import os
import sys
-import subprocess
from methods import detect_darwin_sdk_path
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index aaae03df68..211082d610 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -326,12 +326,12 @@ bool BaseButton::is_keep_pressed_outside() const {
return keep_pressed_outside;
}
-void BaseButton::set_shortcut(const Ref<ShortCut> &p_shortcut) {
+void BaseButton::set_shortcut(const Ref<Shortcut> &p_shortcut) {
shortcut = p_shortcut;
set_process_unhandled_input(shortcut.is_valid());
}
-Ref<ShortCut> BaseButton::get_shortcut() const {
+Ref<Shortcut> BaseButton::get_shortcut() const {
return shortcut;
}
@@ -414,7 +414,7 @@ void BaseButton::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "button_mask", PROPERTY_HINT_FLAGS, "Mouse Left, Mouse Right, Mouse Middle"), "set_button_mask", "get_button_mask");
ADD_PROPERTY(PropertyInfo(Variant::INT, "enabled_focus_mode", PROPERTY_HINT_ENUM, "None,Click,All"), "set_enabled_focus_mode", "get_enabled_focus_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_pressed_outside"), "set_keep_pressed_outside", "is_keep_pressed_outside");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shortcut", PROPERTY_HINT_RESOURCE_TYPE, "ShortCut"), "set_shortcut", "get_shortcut");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shortcut", PROPERTY_HINT_RESOURCE_TYPE, "Shortcut"), "set_shortcut", "get_shortcut");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "group", PROPERTY_HINT_RESOURCE_TYPE, "ButtonGroup"), "set_button_group", "get_button_group");
BIND_ENUM_CONSTANT(DRAW_NORMAL);
diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h
index 12272446d5..8e71931f8b 100644
--- a/scene/gui/base_button.h
+++ b/scene/gui/base_button.h
@@ -50,7 +50,7 @@ private:
bool shortcut_in_tooltip;
bool keep_pressed_outside;
FocusMode enabled_focus_mode;
- Ref<ShortCut> shortcut;
+ Ref<Shortcut> shortcut;
ActionMode action_mode;
struct Status {
@@ -118,8 +118,8 @@ public:
void set_enabled_focus_mode(FocusMode p_mode);
FocusMode get_enabled_focus_mode() const;
- void set_shortcut(const Ref<ShortCut> &p_shortcut);
- Ref<ShortCut> get_shortcut() const;
+ void set_shortcut(const Ref<Shortcut> &p_shortcut);
+ Ref<Shortcut> get_shortcut() const;
virtual String get_tooltip(const Point2 &p_pos) const override;
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index fafbb298b7..cbe0367c7b 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -873,6 +873,7 @@ void ColorPickerButton::_color_changed(const Color &p_color) {
void ColorPickerButton::_modal_closed() {
emit_signal("popup_closed");
+ set_pressed(false);
}
void ColorPickerButton::pressed() {
@@ -976,9 +977,8 @@ void ColorPickerButton::_update_picker() {
popup->add_child(picker);
add_child(popup);
picker->connect("color_changed", callable_mp(this, &ColorPickerButton::_color_changed));
- popup->connect("modal_closed", callable_mp(this, &ColorPickerButton::_modal_closed));
popup->connect("about_to_popup", callable_mp((BaseButton *)this, &BaseButton::set_pressed), varray(true));
- popup->connect("popup_hide", callable_mp((BaseButton *)this, &BaseButton::set_pressed), varray(false));
+ popup->connect("popup_hide", callable_mp(this, &ColorPickerButton::_modal_closed));
picker->set_pick_color(color);
picker->set_edit_alpha(edit_alpha);
emit_signal("picker_created");
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index 2fdcf11ca8..bc70809ad5 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -717,7 +717,7 @@ void PopupMenu::add_multistate_item(const String &p_label, int p_max_states, int
}
#define ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global) \
- ERR_FAIL_COND_MSG(p_shortcut.is_null(), "Cannot add item with invalid ShortCut."); \
+ ERR_FAIL_COND_MSG(p_shortcut.is_null(), "Cannot add item with invalid Shortcut."); \
_ref_shortcut(p_shortcut); \
item.text = p_shortcut->get_name(); \
item.xl_text = tr(item.text); \
@@ -725,7 +725,7 @@ void PopupMenu::add_multistate_item(const String &p_label, int p_max_states, int
item.shortcut = p_shortcut; \
item.shortcut_is_global = p_global;
-void PopupMenu::add_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) {
+void PopupMenu::add_shortcut(const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
items.push_back(item);
@@ -733,7 +733,7 @@ void PopupMenu::add_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bool p_g
child_controls_changed();
}
-void PopupMenu::add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) {
+void PopupMenu::add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
item.icon = p_icon;
@@ -742,7 +742,7 @@ void PopupMenu::add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortC
child_controls_changed();
}
-void PopupMenu::add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) {
+void PopupMenu::add_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
item.checkable_type = Item::CHECKABLE_TYPE_CHECK_BOX;
@@ -751,7 +751,7 @@ void PopupMenu::add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bo
child_controls_changed();
}
-void PopupMenu::add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) {
+void PopupMenu::add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
item.icon = p_icon;
@@ -761,7 +761,7 @@ void PopupMenu::add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<
child_controls_changed();
}
-void PopupMenu::add_radio_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) {
+void PopupMenu::add_radio_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
item.checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON;
@@ -770,7 +770,7 @@ void PopupMenu::add_radio_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_
child_controls_changed();
}
-void PopupMenu::add_icon_radio_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) {
+void PopupMenu::add_icon_radio_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
item.icon = p_icon;
@@ -931,8 +931,8 @@ String PopupMenu::get_item_tooltip(int p_idx) const {
return items[p_idx].tooltip;
}
-Ref<ShortCut> PopupMenu::get_item_shortcut(int p_idx) const {
- ERR_FAIL_INDEX_V(p_idx, items.size(), Ref<ShortCut>());
+Ref<Shortcut> PopupMenu::get_item_shortcut(int p_idx) const {
+ ERR_FAIL_INDEX_V(p_idx, items.size(), Ref<Shortcut>());
return items[p_idx].shortcut;
}
@@ -970,7 +970,7 @@ void PopupMenu::set_item_tooltip(int p_idx, const String &p_tooltip) {
control->update();
}
-void PopupMenu::set_item_shortcut(int p_idx, const Ref<ShortCut> &p_shortcut, bool p_global) {
+void PopupMenu::set_item_shortcut(int p_idx, const Ref<Shortcut> &p_shortcut, bool p_global) {
ERR_FAIL_INDEX(p_idx, items.size());
if (items[p_idx].shortcut.is_valid()) {
_unref_shortcut(items[p_idx].shortcut);
@@ -1209,7 +1209,7 @@ Array PopupMenu::_get_items() const {
return items;
}
-void PopupMenu::_ref_shortcut(Ref<ShortCut> p_sc) {
+void PopupMenu::_ref_shortcut(Ref<Shortcut> p_sc) {
if (!shortcut_refcount.has(p_sc)) {
shortcut_refcount[p_sc] = 1;
p_sc->connect("changed", callable_mp((CanvasItem *)this, &CanvasItem::update));
@@ -1218,7 +1218,7 @@ void PopupMenu::_ref_shortcut(Ref<ShortCut> p_sc) {
}
}
-void PopupMenu::_unref_shortcut(Ref<ShortCut> p_sc) {
+void PopupMenu::_unref_shortcut(Ref<Shortcut> p_sc) {
ERR_FAIL_COND(!shortcut_refcount.has(p_sc));
shortcut_refcount[p_sc]--;
if (shortcut_refcount[p_sc] == 0) {
diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h
index 45a3336747..9535fd07d7 100644
--- a/scene/gui/popup_menu.h
+++ b/scene/gui/popup_menu.h
@@ -61,7 +61,7 @@ class PopupMenu : public Popup {
int _ofs_cache;
int _height_cache;
int h_ofs;
- Ref<ShortCut> shortcut;
+ Ref<Shortcut> shortcut;
bool shortcut_is_global;
bool shortcut_is_disabled;
@@ -114,10 +114,10 @@ class PopupMenu : public Popup {
Array _get_items() const;
void _set_items(const Array &p_items);
- Map<Ref<ShortCut>, int> shortcut_refcount;
+ Map<Ref<Shortcut>, int> shortcut_refcount;
- void _ref_shortcut(Ref<ShortCut> p_sc);
- void _unref_shortcut(Ref<ShortCut> p_sc);
+ void _ref_shortcut(Ref<Shortcut> p_sc);
+ void _unref_shortcut(Ref<Shortcut> p_sc);
bool allow_search;
uint64_t search_time_msec;
@@ -145,12 +145,12 @@ public:
void add_multistate_item(const String &p_label, int p_max_states, int p_default_state = 0, int p_id = -1, uint32_t p_accel = 0);
- void add_shortcut(const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false);
- void add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false);
- void add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false);
- void add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false);
- void add_radio_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false);
- void add_icon_radio_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false);
+ void add_shortcut(const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
+ void add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
+ void add_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
+ void add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
+ void add_radio_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
+ void add_icon_radio_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
void add_submenu_item(const String &p_label, const String &p_submenu, int p_id = -1);
@@ -166,7 +166,7 @@ public:
void set_item_as_checkable(int p_idx, bool p_checkable);
void set_item_as_radio_checkable(int p_idx, bool p_radio_checkable);
void set_item_tooltip(int p_idx, const String &p_tooltip);
- void set_item_shortcut(int p_idx, const Ref<ShortCut> &p_shortcut, bool p_global = false);
+ void set_item_shortcut(int p_idx, const Ref<Shortcut> &p_shortcut, bool p_global = false);
void set_item_h_offset(int p_idx, int p_offset);
void set_item_multistate(int p_idx, int p_state);
void toggle_item_multistate(int p_idx);
@@ -189,7 +189,7 @@ public:
bool is_item_radio_checkable(int p_idx) const;
bool is_item_shortcut_disabled(int p_idx) const;
String get_item_tooltip(int p_idx) const;
- Ref<ShortCut> get_item_shortcut(int p_idx) const;
+ Ref<Shortcut> get_item_shortcut(int p_idx) const;
int get_item_state(int p_idx) const;
int get_current_index() const;
diff --git a/scene/gui/shortcut.cpp b/scene/gui/shortcut.cpp
index 9f5b9c40c2..f8c7bc44a7 100644
--- a/scene/gui/shortcut.cpp
+++ b/scene/gui/shortcut.cpp
@@ -32,20 +32,20 @@
#include "core/os/keyboard.h"
-void ShortCut::set_shortcut(const Ref<InputEvent> &p_shortcut) {
+void Shortcut::set_shortcut(const Ref<InputEvent> &p_shortcut) {
shortcut = p_shortcut;
emit_changed();
}
-Ref<InputEvent> ShortCut::get_shortcut() const {
+Ref<InputEvent> Shortcut::get_shortcut() const {
return shortcut;
}
-bool ShortCut::is_shortcut(const Ref<InputEvent> &p_event) const {
+bool Shortcut::is_shortcut(const Ref<InputEvent> &p_event) const {
return shortcut.is_valid() && shortcut->shortcut_match(p_event);
}
-String ShortCut::get_as_text() const {
+String Shortcut::get_as_text() const {
if (shortcut.is_valid()) {
return shortcut->as_text();
} else {
@@ -53,21 +53,21 @@ String ShortCut::get_as_text() const {
}
}
-bool ShortCut::is_valid() const {
+bool Shortcut::is_valid() const {
return shortcut.is_valid();
}
-void ShortCut::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_shortcut", "event"), &ShortCut::set_shortcut);
- ClassDB::bind_method(D_METHOD("get_shortcut"), &ShortCut::get_shortcut);
+void Shortcut::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_shortcut", "event"), &Shortcut::set_shortcut);
+ ClassDB::bind_method(D_METHOD("get_shortcut"), &Shortcut::get_shortcut);
- ClassDB::bind_method(D_METHOD("is_valid"), &ShortCut::is_valid);
+ ClassDB::bind_method(D_METHOD("is_valid"), &Shortcut::is_valid);
- ClassDB::bind_method(D_METHOD("is_shortcut", "event"), &ShortCut::is_shortcut);
- ClassDB::bind_method(D_METHOD("get_as_text"), &ShortCut::get_as_text);
+ ClassDB::bind_method(D_METHOD("is_shortcut", "event"), &Shortcut::is_shortcut);
+ ClassDB::bind_method(D_METHOD("get_as_text"), &Shortcut::get_as_text);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shortcut", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), "set_shortcut", "get_shortcut");
}
-ShortCut::ShortCut() {
+Shortcut::Shortcut() {
}
diff --git a/scene/gui/shortcut.h b/scene/gui/shortcut.h
index 063d4e43dc..0d7809e5cf 100644
--- a/scene/gui/shortcut.h
+++ b/scene/gui/shortcut.h
@@ -34,8 +34,8 @@
#include "core/input/input_event.h"
#include "core/resource.h"
-class ShortCut : public Resource {
- GDCLASS(ShortCut, Resource);
+class Shortcut : public Resource {
+ GDCLASS(Shortcut, Resource);
Ref<InputEvent> shortcut;
@@ -50,7 +50,7 @@ public:
String get_as_text() const;
- ShortCut();
+ Shortcut();
};
#endif // SHORTCUT_H
diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp
index 8f71aa7cab..d47f771d1d 100644
--- a/scene/gui/tabs.cpp
+++ b/scene/gui/tabs.cpp
@@ -388,6 +388,7 @@ void Tabs::set_current_tab(int p_current) {
}
ERR_FAIL_INDEX(p_current, get_tab_count());
+ previous = current;
current = p_current;
_change_notify("current_tab");
@@ -401,6 +402,10 @@ int Tabs::get_current_tab() const {
return current;
}
+int Tabs::get_previous_tab() const {
+ return previous;
+}
+
int Tabs::get_hovered_tab() const {
return hover;
}
@@ -588,6 +593,7 @@ void Tabs::add_tab(const String &p_str, const Ref<Texture2D> &p_icon) {
void Tabs::clear_tabs() {
tabs.clear();
current = 0;
+ previous = 0;
call_deferred("_update_hover");
update();
}
@@ -605,6 +611,7 @@ void Tabs::remove_tab(int p_idx) {
if (current < 0) {
current = 0;
+ previous = 0;
}
if (current >= tabs.size()) {
current = tabs.size() - 1;
@@ -917,6 +924,7 @@ void Tabs::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_tab_count"), &Tabs::get_tab_count);
ClassDB::bind_method(D_METHOD("set_current_tab", "tab_idx"), &Tabs::set_current_tab);
ClassDB::bind_method(D_METHOD("get_current_tab"), &Tabs::get_current_tab);
+ ClassDB::bind_method(D_METHOD("get_previous_tab"), &Tabs::get_previous_tab);
ClassDB::bind_method(D_METHOD("set_tab_title", "tab_idx", "title"), &Tabs::set_tab_title);
ClassDB::bind_method(D_METHOD("get_tab_title", "tab_idx"), &Tabs::get_tab_title);
ClassDB::bind_method(D_METHOD("set_tab_icon", "tab_idx", "icon"), &Tabs::set_tab_icon);
@@ -970,6 +978,7 @@ void Tabs::_bind_methods() {
Tabs::Tabs() {
current = 0;
+ previous = 0;
tab_align = ALIGN_CENTER;
rb_hover = -1;
rb_pressing = false;
diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h
index 8d7f1aa37d..b94c4a37a1 100644
--- a/scene/gui/tabs.h
+++ b/scene/gui/tabs.h
@@ -77,6 +77,7 @@ private:
bool missing_right;
Vector<Tab> tabs;
int current;
+ int previous;
int _get_top_margin() const;
TabAlign tab_align;
int rb_hover;
@@ -138,6 +139,7 @@ public:
int get_tab_count() const;
void set_current_tab(int p_current);
int get_current_tab() const;
+ int get_previous_tab() const;
int get_hovered_tab() const;
int get_tab_offset() const;
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index 0f74f2e973..e5ab4f9958 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef SCENE_MAIN_LOOP_H
-#define SCENE_MAIN_LOOP_H
+#ifndef SCENE_TREE_H
+#define SCENE_TREE_H
#include "core/io/multiplayer_api.h"
#include "core/os/main_loop.h"
@@ -354,4 +354,4 @@ public:
VARIANT_ENUM_CAST(SceneTree::GroupCallFlags);
-#endif
+#endif // SCENE_TREE_H
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index af900a22db..6069d6c808 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -295,7 +295,7 @@ void register_scene_types() {
OS::get_singleton()->yield(); //may take time to init
- ClassDB::register_class<ShortCut>();
+ ClassDB::register_class<Shortcut>();
ClassDB::register_class<Control>();
ClassDB::register_class<Button>();
ClassDB::register_class<Label>();
@@ -553,6 +553,7 @@ void register_scene_types() {
ClassDB::register_class<VisualShaderNodeTexture>();
ClassDB::register_virtual_class<VisualShaderNodeSample3D>();
ClassDB::register_class<VisualShaderNodeTexture2DArray>();
+ ClassDB::register_class<VisualShaderNodeTexture3D>();
ClassDB::register_class<VisualShaderNodeCubemap>();
ClassDB::register_virtual_class<VisualShaderNodeUniform>();
ClassDB::register_class<VisualShaderNodeUniformRef>();
@@ -565,6 +566,7 @@ void register_scene_types() {
ClassDB::register_class<VisualShaderNodeTextureUniform>();
ClassDB::register_class<VisualShaderNodeTextureUniformTriplanar>();
ClassDB::register_class<VisualShaderNodeTexture2DArrayUniform>();
+ ClassDB::register_class<VisualShaderNodeTexture3DUniform>();
ClassDB::register_class<VisualShaderNodeCubemapUniform>();
ClassDB::register_class<VisualShaderNodeIf>();
ClassDB::register_class<VisualShaderNodeSwitch>();
@@ -871,6 +873,7 @@ void register_scene_types() {
ClassDB::add_compatibility_class("RemoteTransform", "RemoteTransform3D");
ClassDB::add_compatibility_class("RigidBody", "RigidBody3D");
ClassDB::add_compatibility_class("Shape", "Shape3D");
+ ClassDB::add_compatibility_class("ShortCut", "Shortcut");
ClassDB::add_compatibility_class("Skeleton", "Skeleton3D");
ClassDB::add_compatibility_class("SkeletonIK", "SkeletonIK3D");
ClassDB::add_compatibility_class("SliderJoint", "SliderJoint3D");
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index 182aeae5d4..dfc915c5b4 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -951,6 +951,64 @@ void VisualShaderNodeTexture2DArray::_bind_methods() {
VisualShaderNodeTexture2DArray::VisualShaderNodeTexture2DArray() {
}
+
+////////////// Texture3D
+
+String VisualShaderNodeTexture3D::get_caption() const {
+ return "Texture3D";
+}
+
+String VisualShaderNodeTexture3D::get_input_port_name(int p_port) const {
+ if (p_port == 2) {
+ return "sampler3D";
+ }
+ return VisualShaderNodeSample3D::get_input_port_name(p_port);
+}
+
+Vector<VisualShader::DefaultTextureParam> VisualShaderNodeTexture3D::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
+ VisualShader::DefaultTextureParam dtp;
+ dtp.name = make_unique_id(p_type, p_id, "tex3d");
+ dtp.param = texture;
+ Vector<VisualShader::DefaultTextureParam> ret;
+ ret.push_back(dtp);
+ return ret;
+}
+
+String VisualShaderNodeTexture3D::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ if (source == SOURCE_TEXTURE) {
+ return "uniform sampler3D " + make_unique_id(p_type, p_id, "tex3d") + ";\n";
+ }
+ return String();
+}
+
+void VisualShaderNodeTexture3D::set_texture(Ref<Texture3D> p_value) {
+ texture = p_value;
+ emit_changed();
+}
+
+Ref<Texture3D> VisualShaderNodeTexture3D::get_texture() const {
+ return texture;
+}
+
+Vector<StringName> VisualShaderNodeTexture3D::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("source");
+ if (source == SOURCE_TEXTURE) {
+ props.push_back("texture");
+ }
+ return props;
+}
+
+void VisualShaderNodeTexture3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_texture", "value"), &VisualShaderNodeTexture3D::set_texture);
+ ClassDB::bind_method(D_METHOD("get_texture"), &VisualShaderNodeTexture3D::get_texture);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture3D"), "set_texture", "get_texture");
+}
+
+VisualShaderNodeTexture3D::VisualShaderNodeTexture3D() {
+}
+
////////////// Cubemap
String VisualShaderNodeCubemap::get_caption() const {
@@ -4397,6 +4455,74 @@ String VisualShaderNodeTexture2DArrayUniform::generate_code(Shader::Mode p_mode,
VisualShaderNodeTexture2DArrayUniform::VisualShaderNodeTexture2DArrayUniform() {
}
+////////////// Texture3D Uniform
+
+String VisualShaderNodeTexture3DUniform::get_caption() const {
+ return "Texture3DUniform";
+}
+
+int VisualShaderNodeTexture3DUniform::get_output_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeTexture3DUniform::PortType VisualShaderNodeTexture3DUniform::get_output_port_type(int p_port) const {
+ return PORT_TYPE_SAMPLER;
+}
+
+String VisualShaderNodeTexture3DUniform::get_output_port_name(int p_port) const {
+ return "sampler3D";
+}
+
+int VisualShaderNodeTexture3DUniform::get_input_port_count() const {
+ return 0;
+}
+
+VisualShaderNodeTexture3DUniform::PortType VisualShaderNodeTexture3DUniform::get_input_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+
+String VisualShaderNodeTexture3DUniform::get_input_port_name(int p_port) const {
+ return "";
+}
+
+String VisualShaderNodeTexture3DUniform::get_input_port_default_hint(int p_port) const {
+ return "";
+}
+
+String VisualShaderNodeTexture3DUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ String code = _get_qual_str() + "uniform sampler3D " + get_uniform_name();
+
+ switch (texture_type) {
+ case TYPE_DATA:
+ if (color_default == COLOR_DEFAULT_BLACK)
+ code += " : hint_black;\n";
+ else
+ code += ";\n";
+ break;
+ case TYPE_COLOR:
+ if (color_default == COLOR_DEFAULT_BLACK)
+ code += " : hint_black_albedo;\n";
+ else
+ code += " : hint_albedo;\n";
+ break;
+ case TYPE_NORMALMAP:
+ code += " : hint_normal;\n";
+ break;
+ case TYPE_ANISO:
+ code += " : hint_aniso;\n";
+ break;
+ }
+
+ return code;
+}
+
+String VisualShaderNodeTexture3DUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ return String();
+}
+
+VisualShaderNodeTexture3DUniform::VisualShaderNodeTexture3DUniform() {
+}
+
////////////// Cubemap Uniform
String VisualShaderNodeCubemapUniform::get_caption() const {
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index 245435591b..06ad42adf5 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -343,6 +343,29 @@ public:
VisualShaderNodeTexture2DArray();
};
+class VisualShaderNodeTexture3D : public VisualShaderNodeSample3D {
+ GDCLASS(VisualShaderNodeTexture3D, VisualShaderNodeSample3D);
+ Ref<Texture3D> texture;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const override;
+
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+
+ void set_texture(Ref<Texture3D> p_value);
+ Ref<Texture3D> get_texture() const;
+
+ virtual Vector<StringName> get_editable_properties() const override;
+
+ VisualShaderNodeTexture3D();
+};
+
class VisualShaderNodeCubemap : public VisualShaderNode {
GDCLASS(VisualShaderNodeCubemap, VisualShaderNode);
Ref<Cubemap> cube_map;
@@ -1855,6 +1878,29 @@ public:
///////////////////////////////////////
+class VisualShaderNodeTexture3DUniform : public VisualShaderNodeTextureUniform {
+ GDCLASS(VisualShaderNodeTexture3DUniform, VisualShaderNodeTextureUniform);
+
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ virtual String get_input_port_default_hint(int p_port) const override;
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ VisualShaderNodeTexture3DUniform();
+};
+
+///////////////////////////////////////
+
class VisualShaderNodeCubemapUniform : public VisualShaderNodeTextureUniform {
GDCLASS(VisualShaderNodeCubemapUniform, VisualShaderNodeTextureUniform);
diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp
index dca7f59c8c..9e3335b05b 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp
@@ -7190,15 +7190,18 @@ RasterizerStorageRD::RasterizerStorageRD() {
case RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED: {
sampler_state.repeat_u = RD::SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE;
sampler_state.repeat_v = RD::SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE;
+ sampler_state.repeat_w = RD::SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE;
} break;
case RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED: {
sampler_state.repeat_u = RD::SAMPLER_REPEAT_MODE_REPEAT;
sampler_state.repeat_v = RD::SAMPLER_REPEAT_MODE_REPEAT;
+ sampler_state.repeat_w = RD::SAMPLER_REPEAT_MODE_REPEAT;
} break;
case RS::CANVAS_ITEM_TEXTURE_REPEAT_MIRROR: {
sampler_state.repeat_u = RD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT;
sampler_state.repeat_v = RD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT;
+ sampler_state.repeat_w = RD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT;
} break;
default: {
}
diff --git a/thirdparty/README.md b/thirdparty/README.md
index 881590ddf1..58bdafa850 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -564,7 +564,7 @@ comments and a patch is provided in the squish/ folder.
## tinyexr
- Upstream: https://github.com/syoyo/tinyexr
-- Version: git (4dbd05a22f51a2d7462311569b8b0cba0bbe2ac5, 2020)
+- Version: 1.0.0 (e4b7840d9448b7d57a88384ce26143004f3c0c71, 2020)
- License: BSD-3-Clause
Files extracted from upstream source:
diff --git a/thirdparty/tinyexr/tinyexr.cc b/thirdparty/tinyexr/tinyexr.cc
index 969a6d505d..fef8f66c98 100644
--- a/thirdparty/tinyexr/tinyexr.cc
+++ b/thirdparty/tinyexr/tinyexr.cc
@@ -1,2 +1,8 @@
+#if defined(_WIN32)
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+#endif
+
#define TINYEXR_IMPLEMENTATION
#include "tinyexr.h"
diff --git a/thirdparty/tinyexr/tinyexr.h b/thirdparty/tinyexr/tinyexr.h
index 7e8956f7d3..a3e7b23161 100644
--- a/thirdparty/tinyexr/tinyexr.h
+++ b/thirdparty/tinyexr/tinyexr.h
@@ -1,5 +1,7 @@
+#ifndef TINYEXR_H_
+#define TINYEXR_H_
/*
-Copyright (c) 2014 - 2019, Syoyo Fujita and many contributors.
+Copyright (c) 2014 - 2020, Syoyo Fujita and many contributors.
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -63,9 +65,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// End of OpenEXR license -------------------------------------------------
-#ifndef TINYEXR_H_
-#define TINYEXR_H_
-
//
//
// Do this:
@@ -198,11 +197,18 @@ typedef struct _EXRTile {
unsigned char **images; // image[channels][pixels]
} EXRTile;
+typedef struct _EXRBox2i {
+ int min_x;
+ int min_y;
+ int max_x;
+ int max_y;
+} EXRBox2i;
+
typedef struct _EXRHeader {
float pixel_aspect_ratio;
int line_order;
- int data_window[4];
- int display_window[4];
+ EXRBox2i data_window;
+ EXRBox2i display_window;
float screen_window_center[2];
float screen_window_width;
@@ -287,26 +293,29 @@ typedef struct _DeepImage {
extern int LoadEXR(float **out_rgba, int *width, int *height,
const char *filename, const char **err);
-// Loads single-frame OpenEXR image by specifing layer name. Assume EXR image contains A(single channel
-// alpha) or RGB(A) channels.
-// Application must free image data as returned by `out_rgba`
-// Result image format is: float x RGBA x width x hight
-// Returns negative value and may set error string in `err` when there's an
-// error
-// When the specified layer name is not found in the EXR file, the function will return `TINYEXR_ERROR_LAYER_NOT_FOUND`.
+// Loads single-frame OpenEXR image by specifying layer name. Assume EXR image
+// contains A(single channel alpha) or RGB(A) channels. Application must free
+// image data as returned by `out_rgba` Result image format is: float x RGBA x
+// width x hight Returns negative value and may set error string in `err` when
+// there's an error When the specified layer name is not found in the EXR file,
+// the function will return `TINYEXR_ERROR_LAYER_NOT_FOUND`.
extern int LoadEXRWithLayer(float **out_rgba, int *width, int *height,
- const char *filename, const char *layer_name, const char **err);
+ const char *filename, const char *layer_name,
+ const char **err);
//
// Get layer infos from EXR file.
//
-// @param[out] layer_names List of layer names. Application must free memory after using this.
+// @param[out] layer_names List of layer names. Application must free memory
+// after using this.
// @param[out] num_layers The number of layers
-// @param[out] err Error string(wll be filled when the function returns error code). Free it using FreeEXRErrorMessage after using this value.
+// @param[out] err Error string(will be filled when the function returns error
+// code). Free it using FreeEXRErrorMessage after using this value.
//
// @return TINYEXR_SUCCEES upon success.
//
-extern int EXRLayers(const char *filename, const char **layer_names[], int *num_layers, const char **err);
+extern int EXRLayers(const char *filename, const char **layer_names[],
+ int *num_layers, const char **err);
// @deprecated { to be removed. }
// Simple wrapper API for ParseEXRHeaderFromFile.
@@ -336,13 +345,13 @@ extern void InitEXRHeader(EXRHeader *exr_header);
// Initialize EXRImage struct
extern void InitEXRImage(EXRImage *exr_image);
-// Free's internal data of EXRHeader struct
+// Frees internal data of EXRHeader struct
extern int FreeEXRHeader(EXRHeader *exr_header);
-// Free's internal data of EXRImage struct
+// Frees internal data of EXRImage struct
extern int FreeEXRImage(EXRImage *exr_image);
-// Free's error message
+// Frees error message
extern void FreeEXRErrorMessage(const char *msg);
// Parse EXR version header of a file.
@@ -497,8 +506,17 @@ extern int LoadEXRFromMemory(float **out_rgba, int *width, int *height,
#endif // TINYEXR_H_
#ifdef TINYEXR_IMPLEMENTATION
-#ifndef TINYEXR_IMPLEMENTATION_DEIFNED
-#define TINYEXR_IMPLEMENTATION_DEIFNED
+#ifndef TINYEXR_IMPLEMENTATION_DEFINED
+#define TINYEXR_IMPLEMENTATION_DEFINED
+
+#ifdef _WIN32
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h> // for UTF-8
+
+#endif
#include <algorithm>
#include <cassert>
@@ -536,7 +554,18 @@ extern int LoadEXRFromMemory(float **out_rgba, int *width, int *height,
#endif
#if TINYEXR_USE_ZFP
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Weverything"
+#endif
+
#include "zfp.h"
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
#endif
namespace tinyexr {
@@ -619,7 +648,7 @@ namespace miniz {
- Critical fix for the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY bug
(thanks kahmyong.moon@hp.com) which could cause locate files to not find
files. This bug
- would only have occured in earlier versions if you explicitly used this
+ would only have occurred in earlier versions if you explicitly used this
flag, OR if you used mz_zip_extract_archive_file_to_heap() or
mz_zip_add_mem_to_archive_file_in_place()
(which used this flag). If you can't switch to v1.15 but want to fix
@@ -7002,6 +7031,13 @@ void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename,
// Reuse MINIZ_LITTE_ENDIAN macro
+#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || \
+ defined(__i386) || defined(__i486__) || defined(__i486) || \
+ defined(i386) || defined(__ia64__) || defined(__x86_64__)
+// MINIZ_X86_OR_X64_CPU is only used to help set the below macros.
+#define MINIZ_X86_OR_X64_CPU 1
+#endif
+
#if defined(__sparcv9)
// Big endian
#else
@@ -7116,6 +7152,36 @@ static void swap4(unsigned int *val) {
#endif
}
+static void swap4(int *val) {
+#ifdef MINIZ_LITTLE_ENDIAN
+ (void)val;
+#else
+ int tmp = *val;
+ unsigned char *dst = reinterpret_cast<unsigned char *>(val);
+ unsigned char *src = reinterpret_cast<unsigned char *>(&tmp);
+
+ dst[0] = src[3];
+ dst[1] = src[2];
+ dst[2] = src[1];
+ dst[3] = src[0];
+#endif
+}
+
+static void swap4(float *val) {
+#ifdef MINIZ_LITTLE_ENDIAN
+ (void)val;
+#else
+ float tmp = *val;
+ unsigned char *dst = reinterpret_cast<unsigned char *>(val);
+ unsigned char *src = reinterpret_cast<unsigned char *>(&tmp);
+
+ dst[0] = src[3];
+ dst[1] = src[2];
+ dst[2] = src[1];
+ dst[3] = src[0];
+#endif
+}
+
#if 0
static void cpy8(tinyexr::tinyexr_uint64 *dst_val, const tinyexr::tinyexr_uint64 *src_val) {
unsigned char *dst = reinterpret_cast<unsigned char *>(dst_val);
@@ -7363,7 +7429,7 @@ static void WriteAttributeToMemory(std::vector<unsigned char> *out,
out->insert(out->end(), type, type + strlen(type) + 1);
int outLen = len;
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&outLen));
+ tinyexr::swap4(&outLen);
out->insert(out->end(), reinterpret_cast<unsigned char *>(&outLen),
reinterpret_cast<unsigned char *>(&outLen) + sizeof(int));
out->insert(out->end(), data, data + len);
@@ -7379,12 +7445,19 @@ typedef struct {
} ChannelInfo;
typedef struct {
+ int min_x;
+ int min_y;
+ int max_x;
+ int max_y;
+} Box2iInfo;
+
+struct HeaderInfo {
std::vector<tinyexr::ChannelInfo> channels;
std::vector<EXRAttribute> attributes;
- int data_window[4];
+ Box2iInfo data_window;
int line_order;
- int display_window[4];
+ Box2iInfo display_window;
float screen_window_center[2];
float screen_window_width;
float pixel_aspect_ratio;
@@ -7405,15 +7478,15 @@ typedef struct {
channels.clear();
attributes.clear();
- data_window[0] = 0;
- data_window[1] = 0;
- data_window[2] = 0;
- data_window[3] = 0;
+ data_window.min_x = 0;
+ data_window.min_y = 0;
+ data_window.max_x = 0;
+ data_window.max_y = 0;
line_order = 0;
- display_window[0] = 0;
- display_window[1] = 0;
- display_window[2] = 0;
- display_window[3] = 0;
+ display_window.min_x = 0;
+ display_window.min_y = 0;
+ display_window.max_x = 0;
+ display_window.max_y = 0;
screen_window_center[0] = 0.0f;
screen_window_center[1] = 0.0f;
screen_window_width = 0.0f;
@@ -7430,7 +7503,7 @@ typedef struct {
header_len = 0;
compression_type = 0;
}
-} HeaderInfo;
+};
static bool ReadChannelInfo(std::vector<ChannelInfo> &channels,
const std::vector<unsigned char> &data) {
@@ -7469,9 +7542,9 @@ static bool ReadChannelInfo(std::vector<ChannelInfo> &channels,
memcpy(&info.y_sampling, p, sizeof(int)); // int
p += 4;
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&info.pixel_type));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&info.x_sampling));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&info.y_sampling));
+ tinyexr::swap4(&info.pixel_type);
+ tinyexr::swap4(&info.x_sampling);
+ tinyexr::swap4(&info.y_sampling);
channels.push_back(info);
}
@@ -7501,9 +7574,9 @@ static void WriteChannelInfo(std::vector<unsigned char> &data,
int pixel_type = channels[c].pixel_type;
int x_sampling = channels[c].x_sampling;
int y_sampling = channels[c].y_sampling;
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&pixel_type));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&x_sampling));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&y_sampling));
+ tinyexr::swap4(&pixel_type);
+ tinyexr::swap4(&x_sampling);
+ tinyexr::swap4(&y_sampling);
memcpy(p, &pixel_type, sizeof(int));
p += sizeof(int);
@@ -7712,7 +7785,7 @@ static int rleCompress(int inLength, const char in[], signed char out[]) {
if (runEnd - runStart >= MIN_RUN_LENGTH) {
//
- // Compressable run
+ // Compressible run
//
*outWrite++ = static_cast<char>(runEnd - runStart) - 1;
@@ -8056,7 +8129,7 @@ static void wav2Encode(
int p2 = 2; // == 1 << (level+1)
//
- // Hierachical loop on smaller dimension n
+ // Hierarchical loop on smaller dimension n
//
while (p2 <= n) {
@@ -8287,9 +8360,9 @@ const int HUF_DECMASK = HUF_DECSIZE - 1;
struct HufDec { // short code long code
//-------------------------------
- int len : 8; // code length 0
- int lit : 24; // lit p size
- int *p; // 0 lits
+ unsigned int len : 8; // code length 0
+ unsigned int lit : 24; // lit p size
+ unsigned int *p; // 0 lits
};
inline long long hufLength(long long code) { return code & 63; }
@@ -8745,14 +8818,14 @@ static bool hufBuildDecTable(const long long *hcode, // i : encoding table
pl->lit++;
if (pl->p) {
- int *p = pl->p;
- pl->p = new int[pl->lit];
+ unsigned int *p = pl->p;
+ pl->p = new unsigned int[pl->lit];
for (int i = 0; i < pl->lit - 1; ++i) pl->p[i] = p[i];
delete[] p;
} else {
- pl->p = new int[1];
+ pl->p = new unsigned int[1];
}
pl->p[pl->lit - 1] = im;
@@ -9491,35 +9564,48 @@ static bool DecompressPiz(unsigned char *outPtr, const unsigned char *inPtr,
#endif // TINYEXR_USE_PIZ
#if TINYEXR_USE_ZFP
+
struct ZFPCompressionParam {
double rate;
- int precision;
+ unsigned int precision;
+ unsigned int __pad0;
double tolerance;
int type; // TINYEXR_ZFP_COMPRESSIONTYPE_*
+ unsigned int __pad1;
ZFPCompressionParam() {
type = TINYEXR_ZFP_COMPRESSIONTYPE_RATE;
rate = 2.0;
precision = 0;
- tolerance = 0.0f;
+ tolerance = 0.0;
}
};
-bool FindZFPCompressionParam(ZFPCompressionParam *param,
- const EXRAttribute *attributes,
- int num_attributes) {
+static bool FindZFPCompressionParam(ZFPCompressionParam *param,
+ const EXRAttribute *attributes,
+ int num_attributes, std::string *err) {
bool foundType = false;
for (int i = 0; i < num_attributes; i++) {
- if ((strcmp(attributes[i].name, "zfpCompressionType") == 0) &&
- (attributes[i].size == 1)) {
- param->type = static_cast<int>(attributes[i].value[0]);
-
- foundType = true;
+ if ((strcmp(attributes[i].name, "zfpCompressionType") == 0)) {
+ if (attributes[i].size == 1) {
+ param->type = static_cast<int>(attributes[i].value[0]);
+ foundType = true;
+ break;
+ } else {
+ if (err) {
+ (*err) +=
+ "zfpCompressionType attribute must be uchar(1 byte) type.\n";
+ }
+ return false;
+ }
}
}
if (!foundType) {
+ if (err) {
+ (*err) += "`zfpCompressionType` attribute not found.\n";
+ }
return false;
}
@@ -9531,6 +9617,11 @@ bool FindZFPCompressionParam(ZFPCompressionParam *param,
return true;
}
}
+
+ if (err) {
+ (*err) += "`zfpCompressionRate` attribute not found.\n";
+ }
+
} else if (param->type == TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION) {
for (int i = 0; i < num_attributes; i++) {
if ((strcmp(attributes[i].name, "zfpCompressionPrecision") == 0) &&
@@ -9539,6 +9630,11 @@ bool FindZFPCompressionParam(ZFPCompressionParam *param,
return true;
}
}
+
+ if (err) {
+ (*err) += "`zfpCompressionPrecision` attribute not found.\n";
+ }
+
} else if (param->type == TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY) {
for (int i = 0; i < num_attributes; i++) {
if ((strcmp(attributes[i].name, "zfpCompressionTolerance") == 0) &&
@@ -9547,8 +9643,14 @@ bool FindZFPCompressionParam(ZFPCompressionParam *param,
return true;
}
}
+
+ if (err) {
+ (*err) += "`zfpCompressionTolerance` attribute not found.\n";
+ }
} else {
- assert(0);
+ if (err) {
+ (*err) += "Unknown value specified for `zfpCompressionType`.\n";
+ }
}
return false;
@@ -9556,10 +9658,11 @@ bool FindZFPCompressionParam(ZFPCompressionParam *param,
// Assume pixel format is FLOAT for all channels.
static bool DecompressZfp(float *dst, int dst_width, int dst_num_lines,
- int num_channels, const unsigned char *src,
+ size_t num_channels, const unsigned char *src,
unsigned long src_size,
const ZFPCompressionParam &param) {
- size_t uncompressed_size = dst_width * dst_num_lines * num_channels;
+ size_t uncompressed_size =
+ size_t(dst_width) * size_t(dst_num_lines) * num_channels;
if (uncompressed_size == src_size) {
// Data is not compressed(Issue 40).
@@ -9572,22 +9675,24 @@ static bool DecompressZfp(float *dst, int dst_width, int dst_num_lines,
assert((dst_width % 4) == 0);
assert((dst_num_lines % 4) == 0);
- if ((dst_width & 3U) || (dst_num_lines & 3U)) {
+ if ((size_t(dst_width) & 3U) || (size_t(dst_num_lines) & 3U)) {
return false;
}
field =
zfp_field_2d(reinterpret_cast<void *>(const_cast<unsigned char *>(src)),
- zfp_type_float, dst_width, dst_num_lines * num_channels);
+ zfp_type_float, static_cast<unsigned int>(dst_width),
+ static_cast<unsigned int>(dst_num_lines) *
+ static_cast<unsigned int>(num_channels));
zfp = zfp_stream_open(NULL);
if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_RATE) {
- zfp_stream_set_rate(zfp, param.rate, zfp_type_float, /* dimention */ 2,
+ zfp_stream_set_rate(zfp, param.rate, zfp_type_float, /* dimension */ 2,
/* write random access */ 0);
} else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION) {
- zfp_stream_set_precision(zfp, param.precision, zfp_type_float);
+ zfp_stream_set_precision(zfp, param.precision);
} else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY) {
- zfp_stream_set_accuracy(zfp, param.tolerance, zfp_type_float);
+ zfp_stream_set_accuracy(zfp, param.tolerance);
} else {
assert(0);
}
@@ -9600,17 +9705,17 @@ static bool DecompressZfp(float *dst, int dst_width, int dst_num_lines,
zfp_stream_set_bit_stream(zfp, stream);
zfp_stream_rewind(zfp);
- size_t image_size = dst_width * dst_num_lines;
+ size_t image_size = size_t(dst_width) * size_t(dst_num_lines);
- for (int c = 0; c < num_channels; c++) {
+ for (size_t c = 0; c < size_t(num_channels); c++) {
// decompress 4x4 pixel block.
- for (int y = 0; y < dst_num_lines; y += 4) {
- for (int x = 0; x < dst_width; x += 4) {
+ for (size_t y = 0; y < size_t(dst_num_lines); y += 4) {
+ for (size_t x = 0; x < size_t(dst_width); x += 4) {
float fblock[16];
zfp_decode_block_float_2(zfp, fblock);
- for (int j = 0; j < 4; j++) {
- for (int i = 0; i < 4; i++) {
- dst[c * image_size + ((y + j) * dst_width + (x + i))] =
+ for (size_t j = 0; j < 4; j++) {
+ for (size_t i = 0; i < 4; i++) {
+ dst[c * image_size + ((y + j) * size_t(dst_width) + (x + i))] =
fblock[j * 4 + i];
}
}
@@ -9626,31 +9731,33 @@ static bool DecompressZfp(float *dst, int dst_width, int dst_num_lines,
}
// Assume pixel format is FLOAT for all channels.
-bool CompressZfp(std::vector<unsigned char> *outBuf, unsigned int *outSize,
- const float *inPtr, int width, int num_lines, int num_channels,
- const ZFPCompressionParam &param) {
+static bool CompressZfp(std::vector<unsigned char> *outBuf,
+ unsigned int *outSize, const float *inPtr, int width,
+ int num_lines, int num_channels,
+ const ZFPCompressionParam &param) {
zfp_stream *zfp = NULL;
zfp_field *field = NULL;
assert((width % 4) == 0);
assert((num_lines % 4) == 0);
- if ((width & 3U) || (num_lines & 3U)) {
+ if ((size_t(width) & 3U) || (size_t(num_lines) & 3U)) {
return false;
}
// create input array.
field = zfp_field_2d(reinterpret_cast<void *>(const_cast<float *>(inPtr)),
- zfp_type_float, width, num_lines * num_channels);
+ zfp_type_float, static_cast<unsigned int>(width),
+ static_cast<unsigned int>(num_lines * num_channels));
zfp = zfp_stream_open(NULL);
if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_RATE) {
zfp_stream_set_rate(zfp, param.rate, zfp_type_float, 2, 0);
} else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION) {
- zfp_stream_set_precision(zfp, param.precision, zfp_type_float);
+ zfp_stream_set_precision(zfp, param.precision);
} else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY) {
- zfp_stream_set_accuracy(zfp, param.tolerance, zfp_type_float);
+ zfp_stream_set_accuracy(zfp, param.tolerance);
} else {
assert(0);
}
@@ -9663,17 +9770,17 @@ bool CompressZfp(std::vector<unsigned char> *outBuf, unsigned int *outSize,
zfp_stream_set_bit_stream(zfp, stream);
zfp_field_free(field);
- size_t image_size = width * num_lines;
+ size_t image_size = size_t(width) * size_t(num_lines);
- for (int c = 0; c < num_channels; c++) {
+ for (size_t c = 0; c < size_t(num_channels); c++) {
// compress 4x4 pixel block.
- for (int y = 0; y < num_lines; y += 4) {
- for (int x = 0; x < width; x += 4) {
+ for (size_t y = 0; y < size_t(num_lines); y += 4) {
+ for (size_t x = 0; x < size_t(width); x += 4) {
float fblock[16];
- for (int j = 0; j < 4; j++) {
- for (int i = 0; i < 4; i++) {
+ for (size_t j = 0; j < 4; j++) {
+ for (size_t i = 0; i < 4; i++) {
fblock[j * 4 + i] =
- inPtr[c * image_size + ((y + j) * width + (x + i))];
+ inPtr[c * image_size + ((y + j) * size_t(width) + (x + i))];
}
}
zfp_encode_block_float_2(zfp, fblock);
@@ -9682,7 +9789,7 @@ bool CompressZfp(std::vector<unsigned char> *outBuf, unsigned int *outSize,
}
zfp_stream_flush(zfp);
- (*outSize) = zfp_stream_compressed_size(zfp);
+ (*outSize) = static_cast<unsigned int>(zfp_stream_compressed_size(zfp));
zfp_stream_close(zfp);
@@ -10122,8 +10229,10 @@ static bool DecodePixelData(/* out */ unsigned char **out_images,
} else if (compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) {
#if TINYEXR_USE_ZFP
tinyexr::ZFPCompressionParam zfp_compression_param;
- if (!FindZFPCompressionParam(&zfp_compression_param, attributes,
- num_attributes)) {
+ std::string e;
+ if (!tinyexr::FindZFPCompressionParam(&zfp_compression_param, attributes,
+ int(num_attributes), &e)) {
+ // This code path should not be reachable.
assert(0);
return false;
}
@@ -10323,8 +10432,11 @@ static bool DecodeTiledPixelData(
const EXRAttribute *attributes, size_t num_channels,
const EXRChannelInfo *channels,
const std::vector<size_t> &channel_offset_list) {
- assert(tile_offset_x * tile_size_x < data_width);
- assert(tile_offset_y * tile_size_y < data_height);
+ if (tile_size_x > data_width || tile_size_y > data_height ||
+ tile_size_x * tile_offset_x > data_width ||
+ tile_size_y * tile_offset_y > data_height) {
+ return false;
+ }
// Compute actual image size in a tile.
if ((tile_offset_x + 1) * tile_size_x >= data_width) {
@@ -10418,6 +10530,17 @@ static unsigned char **AllocateImage(int num_channels,
return images;
}
+#ifdef _WIN32
+static inline std::wstring UTF8ToWchar(const std::string &str) {
+ int wstr_size =
+ MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), NULL, 0);
+ std::wstring wstr(wstr_size, 0);
+ MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), &wstr[0],
+ (int)wstr.size());
+ return wstr;
+}
+#endif
+
static int ParseEXRHeader(HeaderInfo *info, bool *empty_header,
const EXRVersion *version, std::string *err,
const unsigned char *buf, size_t size) {
@@ -10457,15 +10580,15 @@ static int ParseEXRHeader(HeaderInfo *info, bool *empty_header,
bool has_screen_window_center = false;
bool has_screen_window_width = false;
- info->data_window[0] = 0;
- info->data_window[1] = 0;
- info->data_window[2] = 0;
- info->data_window[3] = 0;
+ info->data_window.min_x = 0;
+ info->data_window.min_y = 0;
+ info->data_window.max_x = 0;
+ info->data_window.max_y = 0;
info->line_order = 0; // @fixme
- info->display_window[0] = 0;
- info->display_window[1] = 0;
- info->display_window[2] = 0;
- info->display_window[3] = 0;
+ info->display_window.min_x = 0;
+ info->display_window.min_y = 0;
+ info->display_window.max_x = 0;
+ info->display_window.max_y = 0;
info->screen_window_center[0] = 0.0f;
info->screen_window_center[1] = 0.0f;
info->screen_window_width = -1.0f;
@@ -10515,6 +10638,14 @@ static int ParseEXRHeader(HeaderInfo *info, bool *empty_header,
tinyexr::swap4(&x_size);
tinyexr::swap4(&y_size);
+ if (x_size > static_cast<unsigned int>(std::numeric_limits<int>::max()) ||
+ y_size > static_cast<unsigned int>(std::numeric_limits<int>::max())) {
+ if (err) {
+ (*err) = "Tile sizes were invalid.";
+ }
+ return TINYEXR_ERROR_UNSUPPORTED_FORMAT;
+ }
+
info->tile_size_x = static_cast<int>(x_size);
info->tile_size_y = static_cast<int>(y_size);
@@ -10586,30 +10717,26 @@ static int ParseEXRHeader(HeaderInfo *info, bool *empty_header,
} else if (attr_name.compare("dataWindow") == 0) {
if (data.size() >= 16) {
- memcpy(&info->data_window[0], &data.at(0), sizeof(int));
- memcpy(&info->data_window[1], &data.at(4), sizeof(int));
- memcpy(&info->data_window[2], &data.at(8), sizeof(int));
- memcpy(&info->data_window[3], &data.at(12), sizeof(int));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&info->data_window[0]));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&info->data_window[1]));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&info->data_window[2]));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&info->data_window[3]));
+ memcpy(&info->data_window.min_x, &data.at(0), sizeof(int));
+ memcpy(&info->data_window.min_y, &data.at(4), sizeof(int));
+ memcpy(&info->data_window.max_x, &data.at(8), sizeof(int));
+ memcpy(&info->data_window.max_y, &data.at(12), sizeof(int));
+ tinyexr::swap4(&info->data_window.min_x);
+ tinyexr::swap4(&info->data_window.min_y);
+ tinyexr::swap4(&info->data_window.max_x);
+ tinyexr::swap4(&info->data_window.max_y);
has_data_window = true;
}
} else if (attr_name.compare("displayWindow") == 0) {
if (data.size() >= 16) {
- memcpy(&info->display_window[0], &data.at(0), sizeof(int));
- memcpy(&info->display_window[1], &data.at(4), sizeof(int));
- memcpy(&info->display_window[2], &data.at(8), sizeof(int));
- memcpy(&info->display_window[3], &data.at(12), sizeof(int));
- tinyexr::swap4(
- reinterpret_cast<unsigned int *>(&info->display_window[0]));
- tinyexr::swap4(
- reinterpret_cast<unsigned int *>(&info->display_window[1]));
- tinyexr::swap4(
- reinterpret_cast<unsigned int *>(&info->display_window[2]));
- tinyexr::swap4(
- reinterpret_cast<unsigned int *>(&info->display_window[3]));
+ memcpy(&info->display_window.min_x, &data.at(0), sizeof(int));
+ memcpy(&info->display_window.min_y, &data.at(4), sizeof(int));
+ memcpy(&info->display_window.max_x, &data.at(8), sizeof(int));
+ memcpy(&info->display_window.max_y, &data.at(12), sizeof(int));
+ tinyexr::swap4(&info->display_window.min_x);
+ tinyexr::swap4(&info->display_window.min_y);
+ tinyexr::swap4(&info->display_window.max_x);
+ tinyexr::swap4(&info->display_window.max_y);
has_display_window = true;
}
@@ -10621,32 +10748,28 @@ static int ParseEXRHeader(HeaderInfo *info, bool *empty_header,
} else if (attr_name.compare("pixelAspectRatio") == 0) {
if (data.size() >= sizeof(float)) {
memcpy(&info->pixel_aspect_ratio, &data.at(0), sizeof(float));
- tinyexr::swap4(
- reinterpret_cast<unsigned int *>(&info->pixel_aspect_ratio));
+ tinyexr::swap4(&info->pixel_aspect_ratio);
has_pixel_aspect_ratio = true;
}
} else if (attr_name.compare("screenWindowCenter") == 0) {
if (data.size() >= 8) {
memcpy(&info->screen_window_center[0], &data.at(0), sizeof(float));
memcpy(&info->screen_window_center[1], &data.at(4), sizeof(float));
- tinyexr::swap4(
- reinterpret_cast<unsigned int *>(&info->screen_window_center[0]));
- tinyexr::swap4(
- reinterpret_cast<unsigned int *>(&info->screen_window_center[1]));
+ tinyexr::swap4(&info->screen_window_center[0]);
+ tinyexr::swap4(&info->screen_window_center[1]);
has_screen_window_center = true;
}
} else if (attr_name.compare("screenWindowWidth") == 0) {
if (data.size() >= sizeof(float)) {
memcpy(&info->screen_window_width, &data.at(0), sizeof(float));
- tinyexr::swap4(
- reinterpret_cast<unsigned int *>(&info->screen_window_width));
+ tinyexr::swap4(&info->screen_window_width);
has_screen_window_width = true;
}
} else if (attr_name.compare("chunkCount") == 0) {
if (data.size() >= sizeof(int)) {
memcpy(&info->chunk_count, &data.at(0), sizeof(int));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&info->chunk_count));
+ tinyexr::swap4(&info->chunk_count);
}
} else {
// Custom attribute(up to TINYEXR_MAX_CUSTOM_ATTRIBUTES)
@@ -10732,14 +10855,14 @@ static void ConvertHeader(EXRHeader *exr_header, const HeaderInfo &info) {
exr_header->screen_window_center[1] = info.screen_window_center[1];
exr_header->screen_window_width = info.screen_window_width;
exr_header->chunk_count = info.chunk_count;
- exr_header->display_window[0] = info.display_window[0];
- exr_header->display_window[1] = info.display_window[1];
- exr_header->display_window[2] = info.display_window[2];
- exr_header->display_window[3] = info.display_window[3];
- exr_header->data_window[0] = info.data_window[0];
- exr_header->data_window[1] = info.data_window[1];
- exr_header->data_window[2] = info.data_window[2];
- exr_header->data_window[3] = info.data_window[3];
+ exr_header->display_window.min_x = info.display_window.min_x;
+ exr_header->display_window.min_y = info.display_window.min_y;
+ exr_header->display_window.max_x = info.display_window.max_x;
+ exr_header->display_window.max_y = info.display_window.max_y;
+ exr_header->data_window.min_x = info.data_window.min_x;
+ exr_header->data_window.min_y = info.data_window.min_y;
+ exr_header->data_window.max_x = info.data_window.max_x;
+ exr_header->data_window.max_y = info.data_window.max_y;
exr_header->line_order = info.line_order;
exr_header->compression_type = info.compression_type;
@@ -10798,7 +10921,7 @@ static void ConvertHeader(EXRHeader *exr_header, const HeaderInfo &info) {
memcpy(exr_header->custom_attributes[i].type, info.attributes[i].type,
256);
exr_header->custom_attributes[i].size = info.attributes[i].size;
- // Just copy poiner
+ // Just copy pointer
exr_header->custom_attributes[i].value = info.attributes[i].value;
}
@@ -10822,21 +10945,30 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header,
num_scanline_blocks = 32;
} else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) {
num_scanline_blocks = 16;
- }
- int data_width = exr_header->data_window[2] - exr_header->data_window[0] + 1;
- int data_height = exr_header->data_window[3] - exr_header->data_window[1] + 1;
+#if TINYEXR_USE_ZFP
+ tinyexr::ZFPCompressionParam zfp_compression_param;
+ if (!FindZFPCompressionParam(&zfp_compression_param,
+ exr_header->custom_attributes,
+ int(exr_header->num_custom_attributes), err)) {
+ return TINYEXR_ERROR_INVALID_HEADER;
+ }
+#endif
+ }
- if ((data_width < 0) || (data_height < 0)) {
+ if (exr_header->data_window.max_x < exr_header->data_window.min_x ||
+ exr_header->data_window.max_y < exr_header->data_window.min_y) {
if (err) {
- std::stringstream ss;
- ss << "Invalid data width or data height: " << data_width << ", "
- << data_height << std::endl;
- (*err) += ss.str();
+ (*err) += "Invalid data window.\n";
}
return TINYEXR_ERROR_INVALID_DATA;
}
+ int data_width =
+ exr_header->data_window.max_x - exr_header->data_window.min_x + 1;
+ int data_height =
+ exr_header->data_window.max_y - exr_header->data_window.min_y + 1;
+
// Do not allow too large data_width and data_height. header invalid?
{
const int threshold = 1024 * 8192; // heuristics
@@ -10938,14 +11070,10 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header,
int tile_coordinates[4];
memcpy(tile_coordinates, data_ptr, sizeof(int) * 4);
- tinyexr::swap4(
- reinterpret_cast<unsigned int *>(&tile_coordinates[0]));
- tinyexr::swap4(
- reinterpret_cast<unsigned int *>(&tile_coordinates[1]));
- tinyexr::swap4(
- reinterpret_cast<unsigned int *>(&tile_coordinates[2]));
- tinyexr::swap4(
- reinterpret_cast<unsigned int *>(&tile_coordinates[3]));
+ tinyexr::swap4(&tile_coordinates[0]);
+ tinyexr::swap4(&tile_coordinates[1]);
+ tinyexr::swap4(&tile_coordinates[2]);
+ tinyexr::swap4(&tile_coordinates[3]);
// @todo{ LoD }
if (tile_coordinates[2] != 0) {
@@ -10960,7 +11088,7 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header,
int data_len;
memcpy(&data_len, data_ptr + 16,
sizeof(int)); // 16 = sizeof(tile_coordinates)
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&data_len));
+ tinyexr::swap4(&data_len);
if (data_len < 4 || size_t(data_len) > data_size) {
// TODO(LTE): atomic
@@ -11081,8 +11209,8 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header,
memcpy(&line_no, data_ptr, sizeof(int));
int data_len;
memcpy(&data_len, data_ptr + 4, sizeof(int));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&line_no));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&data_len));
+ tinyexr::swap4(&line_no);
+ tinyexr::swap4(&data_len);
if (size_t(data_len) > data_size) {
invalid_data = true;
@@ -11098,7 +11226,7 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header,
} else {
// line_no may be negative.
int end_line_no = (std::min)(line_no + num_scanline_blocks,
- (exr_header->data_window[3] + 1));
+ (exr_header->data_window.max_y + 1));
int num_lines = end_line_no - line_no;
@@ -11113,13 +11241,13 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header,
// overflow check
tinyexr_int64 lno =
static_cast<tinyexr_int64>(line_no) -
- static_cast<tinyexr_int64>(exr_header->data_window[1]);
+ static_cast<tinyexr_int64>(exr_header->data_window.min_y);
if (lno > std::numeric_limits<int>::max()) {
line_no = -1; // invalid
} else if (lno < -std::numeric_limits<int>::max()) {
line_no = -1; // invalid
} else {
- line_no -= exr_header->data_window[1];
+ line_no -= exr_header->data_window.min_y;
}
if (line_no < 0) {
@@ -11204,8 +11332,8 @@ static bool ReconstructLineOffsets(
return false;
}
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&y));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&data_len));
+ tinyexr::swap4(&y);
+ tinyexr::swap4(&data_len);
(*offsets)[i] = offset;
@@ -11234,25 +11362,24 @@ static int DecodeEXRImage(EXRImage *exr_image, const EXRHeader *exr_header,
num_scanline_blocks = 16;
}
- int data_width = exr_header->data_window[2] - exr_header->data_window[0];
- if (data_width >= std::numeric_limits<int>::max()) {
+ if (exr_header->data_window.max_x < exr_header->data_window.min_x ||
+ exr_header->data_window.max_x - exr_header->data_window.min_x ==
+ std::numeric_limits<int>::max()) {
// Issue 63
tinyexr::SetErrorMessage("Invalid data width value", err);
return TINYEXR_ERROR_INVALID_DATA;
}
- data_width++;
+ int data_width =
+ exr_header->data_window.max_x - exr_header->data_window.min_x + 1;
- int data_height = exr_header->data_window[3] - exr_header->data_window[1];
- if (data_height >= std::numeric_limits<int>::max()) {
+ if (exr_header->data_window.max_y < exr_header->data_window.min_y ||
+ exr_header->data_window.max_y - exr_header->data_window.min_y ==
+ std::numeric_limits<int>::max()) {
tinyexr::SetErrorMessage("Invalid data height value", err);
return TINYEXR_ERROR_INVALID_DATA;
}
- data_height++;
-
- if ((data_width < 0) || (data_height < 0)) {
- tinyexr::SetErrorMessage("data width or data height is negative.", err);
- return TINYEXR_ERROR_INVALID_DATA;
- }
+ int data_height =
+ exr_header->data_window.max_y - exr_header->data_window.min_y + 1;
// Do not allow too large data_width and data_height. header invalid?
{
@@ -11275,6 +11402,12 @@ static int DecodeEXRImage(EXRImage *exr_image, const EXRHeader *exr_header,
num_blocks = static_cast<size_t>(exr_header->chunk_count);
} else if (exr_header->tiled) {
// @todo { LoD }
+ if (exr_header->tile_size_x > data_width || exr_header->tile_size_x < 1 ||
+ exr_header->tile_size_y > data_height || exr_header->tile_size_y < 1) {
+ tinyexr::SetErrorMessage("tile sizes are invalid.", err);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
size_t num_x_tiles = static_cast<size_t>(data_width) /
static_cast<size_t>(exr_header->tile_size_x);
if (num_x_tiles * static_cast<size_t>(exr_header->tile_size_x) <
@@ -11371,7 +11504,8 @@ static int DecodeEXRImage(EXRImage *exr_image, const EXRHeader *exr_header,
}
}
-static void GetLayers(const EXRHeader& exr_header, std::vector<std::string>& layer_names) {
+static void GetLayers(const EXRHeader &exr_header,
+ std::vector<std::string> &layer_names) {
// Naive implementation
// Group channels by layers
// go over all channel names, split by periods
@@ -11382,22 +11516,22 @@ static void GetLayers(const EXRHeader& exr_header, std::vector<std::string>& lay
const size_t pos = full_name.find_last_of('.');
if (pos != std::string::npos && pos != 0 && pos + 1 < full_name.size()) {
full_name.erase(pos);
- if (std::find(layer_names.begin(), layer_names.end(), full_name) == layer_names.end())
+ if (std::find(layer_names.begin(), layer_names.end(), full_name) ==
+ layer_names.end())
layer_names.push_back(full_name);
}
}
}
struct LayerChannel {
- explicit LayerChannel (size_t i, std::string n)
- : index(i)
- , name(n)
- {}
+ explicit LayerChannel(size_t i, std::string n) : index(i), name(n) {}
size_t index;
std::string name;
};
-static void ChannelsInLayer(const EXRHeader& exr_header, const std::string layer_name, std::vector<LayerChannel>& channels) {
+static void ChannelsInLayer(const EXRHeader &exr_header,
+ const std::string layer_name,
+ std::vector<LayerChannel> &channels) {
channels.clear();
for (int c = 0; c < exr_header.num_channels; c++) {
std::string ch_name(exr_header.channels[c].name);
@@ -11408,8 +11542,7 @@ static void ChannelsInLayer(const EXRHeader& exr_header, const std::string layer
}
} else {
const size_t pos = ch_name.find(layer_name + '.');
- if (pos == std::string::npos)
- continue;
+ if (pos == std::string::npos) continue;
if (pos == 0) {
ch_name = ch_name.substr(layer_name.size() + 1);
}
@@ -11421,7 +11554,8 @@ static void ChannelsInLayer(const EXRHeader& exr_header, const std::string layer
} // namespace tinyexr
-int EXRLayers(const char *filename, const char **layer_names[], int *num_layers, const char **err) {
+int EXRLayers(const char *filename, const char **layer_names[], int *num_layers,
+ const char **err) {
EXRVersion exr_version;
EXRHeader exr_header;
InitEXRHeader(&exr_header);
@@ -11435,8 +11569,8 @@ int EXRLayers(const char *filename, const char **layer_names[], int *num_layers,
if (exr_version.multipart || exr_version.non_image) {
tinyexr::SetErrorMessage(
- "Loading multipart or DeepImage is not supported in LoadEXR() API",
- err);
+ "Loading multipart or DeepImage is not supported in LoadEXR() API",
+ err);
return TINYEXR_ERROR_INVALID_DATA; // @fixme.
}
}
@@ -11452,7 +11586,7 @@ int EXRLayers(const char *filename, const char **layer_names[], int *num_layers,
(*num_layers) = int(layer_vec.size());
(*layer_names) = static_cast<const char **>(
- malloc(sizeof(const char *) * static_cast<size_t>(layer_vec.size())));
+ malloc(sizeof(const char *) * static_cast<size_t>(layer_vec.size())));
for (size_t c = 0; c < static_cast<size_t>(layer_vec.size()); c++) {
#ifdef _MSC_VER
(*layer_names)[c] = _strdup(layer_vec[c].c_str());
@@ -11467,11 +11601,13 @@ int EXRLayers(const char *filename, const char **layer_names[], int *num_layers,
int LoadEXR(float **out_rgba, int *width, int *height, const char *filename,
const char **err) {
- return LoadEXRWithLayer(out_rgba, width, height, filename, /* layername */NULL, err);
+ return LoadEXRWithLayer(out_rgba, width, height, filename,
+ /* layername */ NULL, err);
}
-int LoadEXRWithLayer(float **out_rgba, int *width, int *height, const char *filename, const char *layername,
- const char **err) {
+int LoadEXRWithLayer(float **out_rgba, int *width, int *height,
+ const char *filename, const char *layername,
+ const char **err) {
if (out_rgba == NULL) {
tinyexr::SetErrorMessage("Invalid argument for LoadEXR()", err);
return TINYEXR_ERROR_INVALID_ARGUMENT;
@@ -11487,7 +11623,8 @@ int LoadEXRWithLayer(float **out_rgba, int *width, int *height, const char *file
int ret = ParseEXRVersionFromFile(&exr_version, filename);
if (ret != TINYEXR_SUCCESS) {
std::stringstream ss;
- ss << "Failed to open EXR file or read version info from EXR file. code(" << ret << ")";
+ ss << "Failed to open EXR file or read version info from EXR file. code("
+ << ret << ")";
tinyexr::SetErrorMessage(ss.str(), err);
return ret;
}
@@ -11534,7 +11671,8 @@ int LoadEXRWithLayer(float **out_rgba, int *width, int *height, const char *file
tinyexr::GetLayers(exr_header, layer_names);
std::vector<tinyexr::LayerChannel> channels;
- tinyexr::ChannelsInLayer(exr_header, layername == NULL ? "" : std::string(layername), channels);
+ tinyexr::ChannelsInLayer(
+ exr_header, layername == NULL ? "" : std::string(layername), channels);
if (channels.size() < 1) {
tinyexr::SetErrorMessage("Layer Not Found", err);
@@ -11549,14 +11687,11 @@ int LoadEXRWithLayer(float **out_rgba, int *width, int *height, const char *file
if (ch.name == "R") {
idxR = int(ch.index);
- }
- else if (ch.name == "G") {
+ } else if (ch.name == "G") {
idxG = int(ch.index);
- }
- else if (ch.name == "B") {
+ } else if (ch.name == "B") {
idxB = int(ch.index);
- }
- else if (ch.name == "A") {
+ } else if (ch.name == "A") {
idxA = int(ch.index);
}
}
@@ -11573,11 +11708,13 @@ int LoadEXRWithLayer(float **out_rgba, int *width, int *height, const char *file
for (int it = 0; it < exr_image.num_tiles; it++) {
for (int j = 0; j < exr_header.tile_size_y; j++) {
for (int i = 0; i < exr_header.tile_size_x; i++) {
- const int ii =
- exr_image.tiles[it].offset_x * exr_header.tile_size_x + i;
- const int jj =
- exr_image.tiles[it].offset_y * exr_header.tile_size_y + j;
- const int idx = ii + jj * exr_image.width;
+ const int ii = exr_image.tiles[it].offset_x *
+ static_cast<int>(exr_header.tile_size_x) +
+ i;
+ const int jj = exr_image.tiles[it].offset_y *
+ static_cast<int>(exr_header.tile_size_y) +
+ j;
+ const int idx = ii + jj * static_cast<int>(exr_image.width);
// out of region check.
if (ii >= exr_image.width) {
@@ -11601,7 +11738,8 @@ int LoadEXRWithLayer(float **out_rgba, int *width, int *height, const char *file
}
} else {
for (int i = 0; i < exr_image.width * exr_image.height; i++) {
- const float val = reinterpret_cast<float **>(exr_image.images)[chIdx][i];
+ const float val =
+ reinterpret_cast<float **>(exr_image.images)[chIdx][i];
(*out_rgba)[4 * i + 0] = val;
(*out_rgba)[4 * i + 1] = val;
(*out_rgba)[4 * i + 2] = val;
@@ -11947,11 +12085,22 @@ int LoadEXRImageFromFile(EXRImage *exr_image, const EXRHeader *exr_header,
return TINYEXR_ERROR_INVALID_ARGUMENT;
}
-#ifdef _WIN32
FILE *fp = NULL;
- fopen_s(&fp, filename, "rb");
+#ifdef _WIN32
+#if defined(_MSC_VER) || defined(__MINGW32__) // MSVC, MinGW gcc or clang
+ errno_t errcode =
+ _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"rb");
+ if (errcode != 0) {
+ tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err);
+ // TODO(syoyo): return wfopen_s erro code
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
#else
- FILE *fp = fopen(filename, "rb");
+ // Unknown compiler
+ fp = fopen(filename, "rb");
+#endif
+#else
+ fp = fopen(filename, "rb");
#endif
if (!fp) {
tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err);
@@ -12101,7 +12250,7 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image,
{
int comp = exr_header->compression_type;
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&comp));
+ tinyexr::swap4(&comp);
tinyexr::WriteAttributeToMemory(
&memory, "compression", "compression",
reinterpret_cast<const unsigned char *>(&comp), 1);
@@ -12109,10 +12258,10 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image,
{
int data[4] = {0, 0, exr_image->width - 1, exr_image->height - 1};
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&data[0]));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&data[1]));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&data[2]));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&data[3]));
+ tinyexr::swap4(&data[0]);
+ tinyexr::swap4(&data[1]);
+ tinyexr::swap4(&data[2]);
+ tinyexr::swap4(&data[3]);
tinyexr::WriteAttributeToMemory(
&memory, "dataWindow", "box2i",
reinterpret_cast<const unsigned char *>(data), sizeof(int) * 4);
@@ -12129,7 +12278,7 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image,
{
float aspectRatio = 1.0f;
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&aspectRatio));
+ tinyexr::swap4(&aspectRatio);
tinyexr::WriteAttributeToMemory(
&memory, "pixelAspectRatio", "float",
reinterpret_cast<const unsigned char *>(&aspectRatio), sizeof(float));
@@ -12137,8 +12286,8 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image,
{
float center[2] = {0.0f, 0.0f};
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&center[0]));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&center[1]));
+ tinyexr::swap4(&center[0]);
+ tinyexr::swap4(&center[1]);
tinyexr::WriteAttributeToMemory(
&memory, "screenWindowCenter", "v2f",
reinterpret_cast<const unsigned char *>(center), 2 * sizeof(float));
@@ -12146,7 +12295,7 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image,
{
float w = static_cast<float>(exr_image->width);
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&w));
+ tinyexr::swap4(&w);
tinyexr::WriteAttributeToMemory(&memory, "screenWindowWidth", "float",
reinterpret_cast<const unsigned char *>(&w),
sizeof(float));
@@ -12213,9 +12362,10 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image,
// Use ZFP compression parameter from custom attributes(if such a parameter
// exists)
{
+ std::string e;
bool ret = tinyexr::FindZFPCompressionParam(
&zfp_compression_param, exr_header->custom_attributes,
- exr_header->num_custom_attributes);
+ exr_header->num_custom_attributes, &e);
if (!ret) {
// Use predefined compression parameter.
@@ -12225,7 +12375,7 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image,
}
#endif
- // TOOD(LTE): C++11 thread
+ // TODO(LTE): C++11 thread
// Use signed int since some OpenMP compiler doesn't allow unsigned type for
// `parallel for`
@@ -12257,7 +12407,7 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image,
tinyexr::FP32 f32 = half_to_float(h16);
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&f32.f));
+ tinyexr::swap4(&f32.f);
// line_ptr[x] = f32.f;
tinyexr::cpy4(line_ptr + x, &(f32.f));
@@ -12321,7 +12471,7 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image,
float val = reinterpret_cast<float **>(
exr_image->images)[c][(y + start_y) * exr_image->width + x];
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&val));
+ tinyexr::swap4(&val);
// line_ptr[x] = val;
tinyexr::cpy4(line_ptr + x, &val);
@@ -12538,14 +12688,26 @@ int SaveEXRImageToFile(const EXRImage *exr_image, const EXRHeader *exr_header,
}
#endif
-#ifdef _WIN32
FILE *fp = NULL;
- fopen_s(&fp, filename, "wb");
+#ifdef _WIN32
+#if defined(_MSC_VER) || defined(__MINGW32__) // MSVC, MinGW gcc or clang
+ errno_t errcode =
+ _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"wb");
+ if (errcode != 0) {
+ tinyexr::SetErrorMessage("Cannot write a file: " + std::string(filename),
+ err);
+ return TINYEXR_ERROR_CANT_WRITE_FILE;
+ }
+#else
+ // Unknown compiler
+ fp = fopen(filename, "wb");
+#endif
#else
- FILE *fp = fopen(filename, "wb");
+ fp = fopen(filename, "wb");
#endif
if (!fp) {
- tinyexr::SetErrorMessage("Cannot write a file", err);
+ tinyexr::SetErrorMessage("Cannot write a file: " + std::string(filename),
+ err);
return TINYEXR_ERROR_CANT_WRITE_FILE;
}
@@ -12577,10 +12739,21 @@ int LoadDeepEXR(DeepImage *deep_image, const char *filename, const char **err) {
return TINYEXR_ERROR_INVALID_ARGUMENT;
}
-#ifdef _MSC_VER
+#ifdef _WIN32
FILE *fp = NULL;
- errno_t errcode = fopen_s(&fp, filename, "rb");
- if ((0 != errcode) || (!fp)) {
+#if defined(_MSC_VER) || defined(__MINGW32__) // MSVC, MinGW gcc or clang
+ errno_t errcode =
+ _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"rb");
+ if (errcode != 0) {
+ tinyexr::SetErrorMessage("Cannot read a file " + std::string(filename),
+ err);
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
+#else
+ // Unknown compiler
+ fp = fopen(filename, "rb");
+#endif
+ if (!fp) {
tinyexr::SetErrorMessage("Cannot read a file " + std::string(filename),
err);
return TINYEXR_ERROR_CANT_OPEN_FILE;
@@ -12714,10 +12887,10 @@ int LoadDeepEXR(DeepImage *deep_image, const char *filename, const char **err) {
memcpy(&dy, &data.at(4), sizeof(int));
memcpy(&dw, &data.at(8), sizeof(int));
memcpy(&dh, &data.at(12), sizeof(int));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&dx));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&dy));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&dw));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&dh));
+ tinyexr::swap4(&dx);
+ tinyexr::swap4(&dy);
+ tinyexr::swap4(&dw);
+ tinyexr::swap4(&dh);
} else if (attr_name.compare("displayWindow") == 0) {
int x;
@@ -12728,10 +12901,10 @@ int LoadDeepEXR(DeepImage *deep_image, const char *filename, const char **err) {
memcpy(&y, &data.at(4), sizeof(int));
memcpy(&w, &data.at(8), sizeof(int));
memcpy(&h, &data.at(12), sizeof(int));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&x));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&y));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&w));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&h));
+ tinyexr::swap4(&x);
+ tinyexr::swap4(&y);
+ tinyexr::swap4(&w);
+ tinyexr::swap4(&h);
}
}
@@ -12819,7 +12992,7 @@ int LoadDeepEXR(DeepImage *deep_image, const char *filename, const char **err) {
memcpy(&unpackedSampleDataSize, data_ptr + 20,
sizeof(tinyexr::tinyexr_int64));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&line_no));
+ tinyexr::swap4(&line_no);
tinyexr::swap8(
reinterpret_cast<tinyexr::tinyexr_uint64 *>(&packedOffsetTableSize));
tinyexr::swap8(
@@ -13054,11 +13227,21 @@ int ParseEXRHeaderFromFile(EXRHeader *exr_header, const EXRVersion *exr_version,
return TINYEXR_ERROR_INVALID_ARGUMENT;
}
-#ifdef _WIN32
FILE *fp = NULL;
- fopen_s(&fp, filename, "rb");
+#ifdef _WIN32
+#if defined(_MSC_VER) || defined(__MINGW32__) // MSVC, MinGW gcc or clang
+ errno_t errcode =
+ _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"rb");
+ if (errcode != 0) {
+ tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err);
+ return TINYEXR_ERROR_INVALID_FILE;
+ }
#else
- FILE *fp = fopen(filename, "rb");
+ // Unknown compiler
+ fp = fopen(filename, "rb");
+#endif
+#else
+ fp = fopen(filename, "rb");
#endif
if (!fp) {
tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err);
@@ -13174,11 +13357,21 @@ int ParseEXRMultipartHeaderFromFile(EXRHeader ***exr_headers, int *num_headers,
return TINYEXR_ERROR_INVALID_ARGUMENT;
}
-#ifdef _WIN32
FILE *fp = NULL;
- fopen_s(&fp, filename, "rb");
+#ifdef _WIN32
+#if defined(_MSC_VER) || defined(__MINGW32__) // MSVC, MinGW gcc or clang
+ errno_t errcode =
+ _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"rb");
+ if (errcode != 0) {
+ tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err);
+ return TINYEXR_ERROR_INVALID_FILE;
+ }
#else
- FILE *fp = fopen(filename, "rb");
+ // Unknown compiler
+ fp = fopen(filename, "rb");
+#endif
+#else
+ fp = fopen(filename, "rb");
#endif
if (!fp) {
tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err);
@@ -13270,11 +13463,20 @@ int ParseEXRVersionFromFile(EXRVersion *version, const char *filename) {
return TINYEXR_ERROR_INVALID_ARGUMENT;
}
-#ifdef _WIN32
FILE *fp = NULL;
- fopen_s(&fp, filename, "rb");
+#ifdef _WIN32
+#if defined(_MSC_VER) || defined(__MINGW32__) // MSVC, MinGW gcc or clang
+ errno_t err = _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"rb");
+ if (err != 0) {
+ // TODO(syoyo): return wfopen_s erro code
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
#else
- FILE *fp = fopen(filename, "rb");
+ // Unknown compiler
+ fp = fopen(filename, "rb");
+#endif
+#else
+ fp = fopen(filename, "rb");
#endif
if (!fp) {
return TINYEXR_ERROR_CANT_OPEN_FILE;
@@ -13408,11 +13610,21 @@ int LoadEXRMultipartImageFromFile(EXRImage *exr_images,
return TINYEXR_ERROR_INVALID_ARGUMENT;
}
-#ifdef _WIN32
FILE *fp = NULL;
- fopen_s(&fp, filename, "rb");
+#ifdef _WIN32
+#if defined(_MSC_VER) || defined(__MINGW32__) // MSVC, MinGW gcc or clang
+ errno_t errcode =
+ _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"rb");
+ if (errcode != 0) {
+ tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err);
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
#else
- FILE *fp = fopen(filename, "rb");
+ // Unknown compiler
+ fp = fopen(filename, "rb");
+#endif
+#else
+ fp = fopen(filename, "rb");
#endif
if (!fp) {
tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err);
@@ -13582,5 +13794,5 @@ int SaveEXR(const float *data, int width, int height, int components,
#pragma clang diagnostic pop
#endif
-#endif // TINYEXR_IMPLEMENTATION_DEIFNED
+#endif // TINYEXR_IMPLEMENTATION_DEFINED
#endif // TINYEXR_IMPLEMENTATION